一. Scrapy简介、架构、数据流和项目结构
二. Scrapy入门
1.1 Scrapy简介
Scrapy是:由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。
Scrapy依赖包
Scrapy 是用纯python编写的,它依赖于几个关键的python包(以及其他包):
-
lxml 一个高效的XML和HTML解析器
-
parsel ,一个写在lxml上面的html/xml数据提取库,
-
w3lib ,用于处理URL和网页编码的多用途帮助程序
-
twisted 异步网络框架
-
cryptography 和 pyOpenSSL ,处理各种网络级安全需求
1.2 Scrapy架构
-
Engine。引擎,处理整个系统的数据流处理、触发事务,是整个框架的核心。
-
Item。项目,它定义了爬取结果的数据结构,爬取的数据会被赋值成该Item对象。
-
Scheduler。调度器,接受引擎发过来的请求并将其加入队列中,在引擎再次请求的时候将请求提供给引擎。
-
Downloader。下载器,下载网页内容,并将网页内容返回给蜘蛛。
-
Spiders。蜘蛛,其内定义了爬取的逻辑和网页的解析规则,它主要负责解析响应并生成提取结果和新的请求。
-
Item Pipeline。项目管道,负责处理由蜘蛛从网页中抽取的项目,它的主要任务是清洗、验证和存储数据。
-
Downloader Middlewares。下载器中间件,位于引擎和下载器之间的钩子框架,主要处理引擎与下载器之间的请求及响应。
-
Spider Middlewares。蜘蛛中间件,位于引擎和蜘蛛之间的钩子框架,主要处理蜘蛛输入的响应和输出的结果及新的请求。
1.3 数据流
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。
-
重复第二步到最后一步,直到Scheduler中没有更多的Request,Engine关闭该网站,爬取结束。
通过多个组件的相互协作、不同组件完成工作的不同、组件对异步处理的支持,Scrapy最大限度地利用了网络带宽,大大提高了数据爬取和处理的效率。
1.4 项目结构
Scrapy框架和pyspider不同,它是通过命令行来创建项目的,代码的编写还是需要IDE。项目创建之后,项目文件结构如下所示:
这里各个文件的功能描述如下。
-
scrapy.cfg:它是Scrapy项目的配置文件,其内定义了项目的配置文件路径、部署相关信息等内容。
-
items.py:它定义Item数据结构,所有的Item的定义都可以放这里。
-
pipelines.py:它定义Item Pipeline的实现,所有的Item Pipeline的实现都可以放这里。
-
settings.py:它定义项目的全局配置。
-
middlewares.py:它定义Spider Middlewares和Downloader Middlewares的实现。
-
spiders:其内包含一个个Spider的实现,每个Spider都有一个文件。
note:在指定文件夹下打开cmd窗口,输入 tree/f 命令可以查看该文件夹结构
先安装以下两个库,注意这些库可能有版本更新,旧版本可能会报错,及时安装新版本,尤其是库。
Note: 推荐在anaconda prompt和anaconda powershell prompt窗口中执行如下命令,或者在cmd窗口的base环境中运行,cmd窗口中激活base环境命令如下:
否则如下创建scrapy项目的命令会报错,如下所示,提示默认conda环境未激活
2.1 创建项目
安装完成后就可以使用scrapy命令来创建项目,如下
如下述树状文件结构所示,创建的sousouspider项目文件夹下面包含scrapy.cfg文件和sougouspider子文件夹,子文件夹中包含items.py,middlewares.py,pipelines.py等文件以及spiders子孙文件夹。
2.2 创建Spider
Spider是自己定义的Class,Scrapy用它来从网页里抓取内容,并解析抓取的结果。不过这个Class必须继承Scrapy提供的Spider类scrapy.Spider,还要定义Spider的名称和起始请求,以及怎样处理爬取后的结果的方法。
也可以使用命令行创建一个Spider。比如要生成quotes这个Spider,可以执行如下命令:
进入刚才创建的sougouspider文件夹,然后执行genspider命令。第一个参数是Spider的名称,第二个参数是网站域名。执行完毕之后,spiders文件夹中多了一个sgspider.py,它就是刚刚创建的Spider
sgspider内容如下所示:
这里有三个属性——、和,还有一个方法。
-
,它是每个项目唯一的名字,用来区分不同的Spider。
-
,它是允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过滤掉。
-
,它包含了Spider在启动时爬取的url列表,初始请求是由它来定义的。
-
,它是Spider的一个方法。默认情况下,被调用时里面的链接构成的请求完成下载执行后,返回的响应就会作为唯一的参数传递给这个函数。该方法负责解析返回的响应、提取数据或者进一步生成要处理的请求。
2.3 创建Item
Item是保存爬取数据的容器,它的使用方法和字典类似。不过,相比字典,Item多了额外的保护机制,可以避免拼写错误或者定义字段错误。
创建Item需要继承类,并且定义类型为的字段。观察目标网站,我们可以获取到到内容有url,page等。
scrapy默认创建的items.py内容如下
定义Item,此时将items.py修改如下:
其中visit_url,page,rank和 title 是 sgspider中定义的变量
2.4 修改settings.py
创建sougouspider默认生成的settings.py的内容如下
修改后的settings.py
注意:pipelines.py和middlewares.py文件使用原默认内容。关于__init__.py , 在Python工程里,当python检测到一个目录下存在__init__.py文件时,python就会把它当成一个模块(module)。__init__.py可以是一个空文件,也可以有非常丰富的内容。
2.5 修改默认生成的spider文件
修改后的sgspider.py
为了应对网站的反爬虫,采用了更换动态ip和伪装header的措施,采用如下代码将更换动态ip和伪装header的模块导入到在上述spider文件中。(将模块命名为IP,将free_ip.py和get_cookies.py放入该IP文件夹中)
from IP.free_ip import get_random_proxy
from IP.get_cookies import get_new_cookies,get_new_headers
free_ip.py
注意:上述文件中使用了ip代理池,代理池的构建参考【学习笔记】WSL2、Docker以及docker-compose安装及环境配置_bu懂就问的博客-CSDN博客_wsl2和docker
利用scrapy进行爬虫之前需要开启docker,并在代理池相应文件夹下(本案例中是ProxyPool-master文件夹)打开cmd命令行窗口,运行以下命令才能够在 http://127.0.0.1:5555/random 端口获取代理ip,上述free_ip.py才能够正常执行
docker-compose up
崔庆才代理池github地址如下,
get_cookies.py
注意:上述get_cookies.py函数是为了生成cookie信息,其中除了导入get_random_proxy()函数生成代理ip之外,还从fake_useragent库导入了UserAgent函数,user-agent可以由fake_useragent随机生成。cookie中的部分信息是基于代理ip访问搜狗视频获取的。
fake_useragent库的安装可以使用如下命令,
2.6 运行scrapy框架
本案例在运行之前需要
1. 开启docker软件
2. 在ProxyPool-master文件夹中执行 docker-compose up 获取动态代理ip
本案例中ProxyPool-master文件夹位于
3. 修改项目爬虫文件中的查询关键词。本案例中,爬虫文件位于
4. 之后可以在scrapy项目文件夹中执行下述命令
5. 运行完之后会将items.py中的变量以字典的形式保存为.json文件,其中中文信息尚未进行utf8转码,可以编写python脚本进一步进行数据清洗和转换。下面的脚本将其转换成markdown链接格式。执行以下命令
conver_json.py
参考资料和链接
【scrapy爬虫】最新sogou搜狗搜索 机智操作绕过反爬验证码(搜狗微信公众号文章同理)_彡千的博客-CSDN博客
GitHub - hellysmile/fake-useragent: up to date simple useragent faker with real world database
GitHub - Python3WebSpider/ProxyPool: An Efficient ProxyPool with Getter, Tester and Server
Scrapy框架的使用之Scrapy框架介绍
崔庆才. python3网络爬虫开发实战