爬虫---抓取亚马逊热销书籍前100

闲来无事扒个网页解闷
首先找个软柿子捏
亚马逊热销排行榜对爬虫的限制并不多
页面连ajx请求都不用发,更没用JS渲染,
只要有网址直接get出所有的数据
用的关于获取网页资源,只用到requests库

首先还是要先来看一下网页
这里写图片描述
每个爬虫新手遇到这样一个如此坦荡的网页,
都会觉得在JS横行的时代,这么天真朴素的网页真是出淤泥而不不染

首先谈思路

主页的链接是写死在代码里的,
解析第一页的时候,第一页的结尾会出现后面的页码和下一页,
首先遵循空间顺序解析出当前页的图书信息,然后找出下一页那个按钮对应的链接,
获取下一页的内容,重复上一步的动作
直到无下一页,获取亚马逊页面结束
然后从页面中获取书籍信息什么的都比较简单

开始上代码

import requests, gevent, random, time
from bs4 import BeautifulSoup
from gevent import monkey
monkey.patch_all()              # 打补丁

用request库获取页面
协程处理多任务
用soup解析页面
打补丁

    def __init__(self):
        self.url = "https://www.amazon.cn/gp/bestsellers/books/ref=sv_b_3#1"
        self.tasks_list = []            # 因为有页面请求等待时间,这个列表用来存储任务
        self.index = 1                  # 记录图书序号
        # 开始解析页面,当有下一页时,改变self.url,再次调用handle_page,直到无下一页
        self.handle_page()

实例初始化实现的功能都写在注释里了,这个类不能代码复用,所以在init里没写传参功能

    def get_page(self,url):
        """输入链接返回resopnse.text
        不设防网页,简单构造请求头即可"""
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
        }
        try:
            html = requests.get(url, headers=headers).text
            return html
        except Exception as e:
            print(e)
            return None

就是给requests的get方法加了个请求头,多个打印异常功能
不过返回的是resopnse.text不是response

    def handle_page(self):
        """解析当前页面"""
        # 处理的是self.url 当前页资源获取完毕时,若得到下一页的链接,会改变这个值,再调用该函数
        html = self.get_page(self.url)
        if not html:                    # 若在取得下一页链接,但是获取页面失败,即停止
            gevent.joinall(self.tasks_list)
        # 处理当页图书
        soup = BeautifulSoup(html, "lxml")
        li_list = soup.select('li[class="zg-item-immersion"]')
        for li in li_list:
            img_url = li.select('img')[0].attrs['src']          # 图片链接
            book = li.select('img')[0].attrs['alt']             # 书名
            book = book.replace(":", "")                        # 书名去冒号,否则会路径错误
            author = li.select('span[class="a-size-small a-color-base"]')[0].get_text()      # 作者名
            path = "F:\A_code\Spider\Amazon\亚马逊热销前100/"+"%s" \
                   "%s" \                                       
                   "NO.%d.jpg"%(book, author, self.index)       # 拼接图片保存路径
            # 接下来就是获取链接与写入本地,需要传入链接和路径
            self.tasks_list.append(gevent.spawn(self.down_img, img_url, path))
            self.index += 1

        # 下一页问题
        a_last = soup.select('li[class="a-last"]')
        if a_last:
            # 如果有下一页,获取下一页地址
            a_href = a_last[0].select('a')[0].attrs['href']
            self.url = a_href                           # 切换要处理的地址
            self.handle_page()
        else:
            # 如果没有,说明任务加载完毕
            gevent.joinall(self.tasks_list)

**爬虫的主要功能在这个方法里
这个方法的逻辑是**

  1. 解析页面,获取当前页排行榜中的图书信息
  2. 图书信息包括,书名,作者,图片链接
  3. 根据书名作者,构建每个图书的写入路径
  4. 把链接与路径传入下载函数中
  5. 解析是否有下一页
  6. 存在下一页,改变self.url调用自身
  7. 不存在,认为已获取全部资源,joinall
  8. 若下一页获取失败,认为以获取全部资源,joinall
@staticmethod
    def down_img(img_url, path):
        """下载图片进本地"""
        time.sleep(random.randint(1, 2))                # 随机睡眠1,2秒避免访问频率过高
        img = requests.get(img_url).content             # 获取二进制资源
        with open(path, "wb")as f:                      # 二进制写入
            f.write(img)

一个简单的爬取类就写完了

amazon = Amazon_books()

最后,上一张爬取结果
这里写图片描述

代码我都是按顺序贴的,我就不再贴重贴完整代码了
欢迎大家一起讨论

猜你喜欢

转载自blog.csdn.net/brook_/article/details/80471784