乐趣区

关于python:Scrapy-豆瓣搜索页爬虫

Scrapy 豆瓣搜寻页爬虫

应用 scrapy 爬虫框架对豆瓣图书搜寻后果进行爬取

Scrapy

Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的利用框架

能够利用在包含数据挖掘,信息处理或存储历史数据等一系列的程序

它提供了多种类型爬虫的基类,如 BaseSpider、CrawlSpider 等

次要组件

Scrapy 框架次要由 五大组件 组成

  1. 调度器 (Scheduler)
    调度器,说白了把它假如成为一个 URL 的优先队列,由它来决定下一个要抓取的网址是什么,同时去除反复的网址,用户能够本人的需要定制调度器。
  2. 下载器 (Downloader)
    下载器,是所有组件中累赘最大的,它用于高速地下载网络上的资源
    Scrapy 的下载器代码不会太简单,但效率高,次要的起因是 Scrapy 下载器是建设在 twisted 这个高效的 异步模型上的
  3. 爬虫(Spider)

    爬虫,是用户最关怀的部份。用户定制本人的爬虫(通过定制正则表达式等语法),用于从特定的网页中提取本人须要的信息,即所谓的实体(Item)。用户也能够从中提取出链接, 让 Scrapy 持续抓取下一个页面

  4. 实体管道(Item Pipeline)

    实体管道,用于解决爬虫 (spider) 提取的实体(Item)

次要的性能是长久化实体、验证实体的有效性、革除不须要的信息

  1. Scrapy 引擎(Scrapy Engine)

    Scrapy 引擎是整个框架的外围
    它用来管制调试器、下载器、爬虫。实际上,引擎相当于计算机的 CPU, 它管制着整个流程

数据流(Data flow)

Scrapy 中的数据流由执行引擎管制,其过程如下:

  1. 引擎关上一个网站,找到解决该网站的 Spider 并向该 spider 申请第一个要爬取的 URL(s)
  2. 引擎从 Spider 中获取到第一个要爬取的 URL 并在调度器 (Scheduler) 以 Request 调度
  3. 引擎向调度器申请下一个要爬取的 URL
  4. 调度器返回下一个要爬取的 URL 给引擎,引擎将 URL 通过下载中间件 (request 方向) 转发给下载器(Downloader)
  5. 一旦页面下载结束,下载器生成一个该页面的 Response,并将其通过下载中间件 (response 方向) 发送给引擎
  6. 引擎从下载器中接管到 Response 并通过 Spider 中间件 (输出方向) 发送给 Spider 解决
  7. Spider 解决 Response 并返回爬取到的 Item 及 (跟进的) 新的 Request 给引擎
  8. 引擎将 (Spider 返回的) 爬取到的 Item 给 Item Pipeline,将(Spider 返回的)Request 给调度器
  9. (从第二步)反复直到调度器中没有更多地 request,引擎敞开该网站

简略应用

创立我的项目 scrapy startproject xxx
创立爬虫 scrapy genspider xxx(爬虫名)xxx.com(爬取域)
生成文件 scrapy crawl xxx -o xxx.json (生成 json/csv 文件)
运行爬虫 scrapy crawl XXX
列出所有爬虫 scrapy list

scrapy 我的项目目录构造

通过命令 scrapy startproject tutorial 创立一个新的我的项目tutorial

将会创立蕴含下列内容的 tutorial 目录

tutorial/                        
    scrapy.cfg            # 我的项目的配置文件
    tutorial/            # 该项目标 python 模块之后将在此退出代码
        __init__.py
        items.py        # 我的项目中的 item 文件
        pipelines.py    # 我的项目中的 pipelines 文件
        settings.py        # 我的项目的设置文件
        spiders/        # 搁置 spider 代码的目录
            __init__.py
            ...

应用 scrapy 爬取豆瓣搜寻页

剖析

https://search.douban.com/movie/subject_search?search_text={search_text}&cat=1002&start={start}

search_text 搜寻关键字

cat 搜寻类别

start 开始的条数

url 规定能够实用到图书电影搜寻页面,前面的爬取也一样

爬取后发现页面信息都无奈获取 ,然而能够找到有个window.__DATA__ 猜想数据都被加密成了这串字符串

一轮百度发现有大佬把加密的 js 代码提取进去了!

于是间接给出大佬的链接豆瓣读书搜寻页的 window.__DATA__的解密

解决了这个问题其余的就很好爬取了

代码

残缺代码见 github 仓库

提取出的 js 在third_party/main.js

class DoubanBookSearchSpider(scrapy.Spider):
    name = 'douban_book_search'
    allowed_domains = ['douban.com']

    def __init__(self,keyword=None,start=None,*args, **kwargs):
        super(DoubanBookSearchSpider, self).__init__(*args, **kwargs)
        self.keyword = keyword
        self.start = start
        self.start_urls.append(f'https://search.douban.com/book/subject_search?search_text={self.keyword}&cat=1001&start={self.start}')

    def parse(self, response):
        r = re.search('window.__DATA__ ="([^"]+)"', response.text).group(1)
        # 导入 js
        file_path = pathlib.Path.cwd() / 'third_party/main.js'
        with open(file_path, 'r', encoding='gbk') as f:
            decrypt_js = f.read()
        ctx = execjs.compile(decrypt_js)
        data = ctx.call('decrypt', r)
        for item in data['payload']['items']:
            if item.get('rating', None):
                cover_url = item['cover_url']
                score = item['rating']['value']
                score_num = item['rating']['count']
                url = item['url']
                abstract = item['abstract']
                title = item['title']
                id = item['id']
                yield DouBanBookSearchItem(
                    cover_url=cover_url,
                    score=score,
                    score_num=score_num,
                    url=url,
                    abstract=abstract,
                    title=title,
                    id=id)

参考

爬虫框架 Scrapy 集体总结(具体)相熟

架构概览

Scrapy 爬虫框架,入门案例(十分具体)

豆瓣读书搜寻页的 window.__DATA__的解密

退出移动版