Python 爬虫基础之 Scrapy 框架详解
本文章中所有内容仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关。
1. 简介
Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架,是目前 Python 中最受欢迎的爬虫框架之一,简单、方便、易上手。 它的应用领域很多,比如网络爬虫开发、数据挖掘、数据监测、自动化测试等。
Scrapy 吸引人的地方在于它是一个框架,将 request (异步调度和处理)、下载器(多线程的 Downloader)、解析器(selector)和 twisted(异步处理)等封装在一起,任何人都可以根据需求方便的修改项目。它也提供了多种类型爬虫的基类,如 BaseSpider、sitemap 爬虫等,最新版本又提供了 Web2.0 爬虫的支持。
官方网址是 https://scrapy.org/
2. Scrapy的安装
使用 pip 直接安装:
1 | pip install scrapy |
Scrapy 依赖的库比较多,比如 lxml、Twisted、pyOpenSSL 等等,我这边的建议是,先执行pip install scrapy
命令,查看安装提示是否报错,如报错就根据报错信息将缺少的依赖用 pip 安装即可,这些对于开发人员是属于最基本的东西,所以我就不放详细过程了。
3. Scrapy的架构
架构组件:
- Engine(引擎): 处理整个系统的数据流处理、触发事务,是整个框架的核心、调度中心,相当于爬虫的 “大脑”。
- Item(项目): 它定义了爬取结果的数据结构,爬取的数据会被赋值成该 Item 对象,也就是我们对数据进行后期过滤或存储的地方。
- Scheduler(调度器): 简单来说就是一个队列,接受引擎发过来的请求并将其加入队列中,在引擎再次请求的时候将请求提供给引擎。
- Downloader(下载器): 负责下载引擎发送过来的所有 request 请求,并将获得的 response 内容返回给引擎,再由引擎将 response 交管给 Spiders 来进行解析。
- Spiders(爬虫): 负责处理所有的 response,从中解析数据,其内定义了爬取的逻辑和网页的解析规则 ,并将需要跟进的 URL 提交给引擎,再次进入 Scheduler。
- Item Pipeline(项目管道): 就是我们封装去重类、存储类的地方,负责处理 Spiders 中获取到的数据并且进行后期的处理,过滤或者存储等等,当页面被爬虫解析所需的数据存入 Item 后,将被发送到 Pipeline,并经过几个特定的次序处理数据,最后存入本地文件或存入数据库。
- Downloader Middlewares(下载器中间件): 可以当做是一个可自定义扩展下载功能的组件,是在引擎及下载器之间的特定钩子(specific hook),主要处理引擎与下载器之间的请求及响应。通过设置下载器中间件可以实现爬虫自动更换 user-agent、IP 等功能。
- Spider Middlewares(爬虫中间件): 在引擎及 Spider 之间的特定钩子(specific hook),主要处理 Spider 的输入(response)和输出(items 及 requests)。自定义扩展、引擎和 Spider 之间通信功能的组件,通过插入自定义代码来扩展 Scrapy 功能。
注意:所有模块(除引擎外)之间是相互独立的,只跟引擎进行交互,并不能直接互相交互。即各大组件(除引擎)之间一定是不能够直接进行交流的。
4. Scrapy的数据流程
- Engine 首先打开一个网站,找到处理该网站的 Spider ,并向该 Spider 获取第一个要爬取的 URL。
- Engine 从 Spider 处获取到第一个要爬取的 URL ,并通过 Scheduler 以 Request 的形式调度。
- Engine 向 Scheduler 请求下一个要爬取的 URL。
- Scheduler 返回下一个要爬取的 URL 给 Engine,Engine 将 URL 通过 Downloader Middlewares 转发给 Downloader下载。
- 一旦页面下载完毕, Downloader 生成该页面的 Response,并将其通过 Downloader Middlewares 发送给 Engine。
- Engine 从下载器中接收到 Response,并将其通过 Spider Middlewares 发送给 Spider 处理。
- Spider 处理 Response ,并返回爬取到的 Item 及新的 Request 给 Engine。
- Engine 将 Spider 返回的 Item 给 Item Pipeline,将新的 Request 给 Scheduler。
- 重复第
2
步到第8
步,直到 Scheduler 中没有更多的 Request,Engine 关闭该网站,爬取结束。
用户只需要将自己的爬取请求输入到对应的 Spider 中,同时将自己对文件的加工请求写入到对应的 Item Pipeline 中,所以一般使用 Scrapy 框架都只修改 Spider 和 Item Pipeline。
5. Scrapy开发流程
下面以爬取慕课网免费课程(https://www.imooc.com/course/list)第一页信息为例概述开发 Scrapy 项目的流程。
5.1 创建项目
进入待创建项目所在的文件夹下,执行scrapy startproject MyReptile
命令创建项目,MyReptile
是项目名称。
在 PyCharm 中点击File
,选择Open
,找到刚刚创建的项目并打开:
打开项目之后可以看到,我们创建的项目目录结构如下:
5.2 创建Spider
Spider 是自定义的类,Scrapy 用它从网页中抓取数据,并解析抓取的结果。这个类必须继承 Scrapy 提供的 Spider 类scrapy.Spider
,并定义 Spider 的名称和起始请求,以及怎样处理爬取结果的方法,
进入刚刚创建的文件夹,执行命令scrapy genspider myspider www.imooc.com
创建一个 Spider,myspider
是 Spider 名称,www.imooc.com
是网站域名。
执行完毕之后,spiders
文件夹下就生成了一个myspider.py
文件:
文件代码中有三个属性和一个方法:
- name: 每个 spider 的名字,用来区分不同的 spider;
- allowed_domains: 允许爬取的域名,如果初始或后续的请求链接不是这个域名下的就会被过滤掉;
- start_urls: Spider 在启动时进行爬取的 URL 列表,也就是爬虫的起始地址,可以是多个 URL,一般是一个,后续的 URL 则从初始的 URL 获取到的 response 中提取;
- parse(): 被调用时,每个初始 URL 完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。该方法负责解析返回的数据,提取数据(生成 item)以及生成需要进一步处理的 URL 的 Request 对象。
5.3 创建Item
创建完 Spider 文件之后,接着定义一个容器来保存要爬取的数据,我们对items.py
文件进行更改或者创建一个新的文件来定义 item 都行。
创建 Item 需要继承 scrapy.Item 类,并且定义类型为 scrapy.Field 的字段。例如我们要爬取慕课网站课程的信息,包括课程名称,课程 URL,课程图片 URL,课程描述,学习人数。
1 | import scrapy |
5.4 编写Spider
之后编写 Spider 中parse()
的内容,parse()
方法的参数 response 是 start_urls
里 URL 爬取后的结果,所以在parse()
中,我们可以直接对 response 的内容进行解析:
1 | import scrapy |
5.5 运行Spider
执行完以上步骤后,我们可以执行命令scrapy crawl myspider
运行爬虫,控制台就会给出爬取的数据。
运行完 Scrapy 后,我们只在控制台看到了输出结果,我们可以利用 Scrapy 提供的 Feed Exports 轻松抓取输出的结果。 例如,我们想将结果保存成 csv 文件,可以在 Pycharm 的 Terminal 窗口中执行如下命令:crawl myspider -o myspider.csv
。
输出格式还支持很多种,例如 json、 xml 、 pickle 、 marshal 等。 下面命令对应的输出分别为 json 、 xml 、 pickle 、 marshal 格式以及远程输出。
1 | scrapy crawl myspider -o myspider.json |
其中, ftp 输出需要正确配置用户名、密码、地址、输出路径,否则会报错。
参考文献
【1】https://zhuanlan.zhihu.com/p/598764670
【2】https://zhuanlan.zhihu.com/p/431078183?utm_id=0
【3】https://blog.csdn.net/weixin_52245535/article/details/128695051
【4】https://www.cnblogs.com/hsiang/p/15139627.html
【5】https://m.biancheng.net/view/2027.html
【6】https://www.zhihu.com/question/439914883/answer/2607880092
【7】https://www.jianshu.com/p/063026368b3c
【8】https://www.coonote.com/python-note/python-scrapy-intro.html
【9】https://www.bilibili.com/video/BV1Db4y1m7Ho?p=90