Scrapy
Scrapy
简介
- 什么是scrapy —— 异步爬虫框架
- scrapy的好处:
- 可配置和扩展性高
- 框架基于异步(Twisted异步网络框架)
Scrapy框架架构
- Scrapy引擎(Engine) —— 爬虫工作的核心,负责控制数据流在系统中所有组件中的流转,并在相应动作发生时触发事件
- 调度器(Scheduler) —— 从引擎接收Request并将它们入队,以便之后引擎请求它们时提供给引擎
- 下载器(Downloader) —— 负责获取页面数据并提供给引擎,而后提供给Spiders
- Spiders —— 用户编写用于分析由下载器返回的Response,并提取出item和额外跟进的URL的类
- Item Pipeline —— 负责处理被Spider提取出来的Item(清理、验证及持久化,如存到数据库中)
- 中间件
- 下载器中间件(Downloader Middlewares) —— 是在引擎和下载器之间的特定hook,处理下载器传递给引擎的Response
- Spider中间件(Spider Middlewares) —— 是在引擎和Spiders中间的特定hook,处理Spiders的输入(接收来自下载器的Response)和输出(发送Items给Item Pipeline以及发送Request给调度器)
组件 | 功能 | 实现方式 |
---|---|---|
Scrapy Engine(引擎) | 负责数据和信号在不同模块之间的传递 | Scrapy已实现 |
Scheduler(调度器) | 一个负责存放引擎发过来的request请求的队列 | Scrapy已实现 |
Downloader(下载器) | 下载引擎发送过来的requests请求,并放回给引擎 | Scrapy已实现 |
Spider(爬虫) | 处理引擎发送来的response,提取数据和url,并发送给引擎 | 需要自己实现 |
Item Pipeline(管道) | 处理引擎发送过来的数据,如存储 | 需要自己实现 |
Downloader Middlewares(下载中间件) | 可以自定义下载的扩展,比如设置代理、请求头等 | 根据自己需要实现(一般不用重写) |
Spider Middlewares(爬虫中间件) | 可以自定义requests请求和response过滤 | 根据自己需要实现(一般不用重写) |
Scrapy数据流过程
- 从Spiders中获取第一个需要爬取的URL
- 使用Scheduler调度Request,并向Scheduler请求下一个要爬取的URL
- Scheduler返回下一个要爬取的URL给引擎
- 引擎将URL通过Downloader Middlewares转发给Downloader
- 只要页面下载完毕,下载器生成一个该页面的Response,并将其通过Downloader Middlewares发送给引擎
- 引擎从Downloader中接收到Response并通过Spider Middlewares发送给Spiders处理
- Spiders处理Response并返回爬取到的Items及新的Requests给引擎
- 引擎将爬取到的Items给Item Pipeline,然后将Request给Scheduler
- 重复1—8步,直到Scheduler中没有更多的URL
Scrapy快速入门
Scrapy重要命令
命令 | 说明 | 格式 |
---|---|---|
stratproject | 创建一个新工程 | scrapy startproject <name> [dir] |
genspider | 创建一个爬虫 | scrapy genspider [options] <name> <domain> |
settings | 获得爬虫配置信息 | scrapysettings [options] |
crawl | 运行一个爬虫 | scrapy crawl <spider> |
list | 列出工程中所有爬虫 | scrapy list |
shell | 启动URL吊事命令行 | scrapy shell [url] |
注意:命令的操作均在终端进行
创建scrapy项目
-
创建Scrapy项目(myspider举例)
scrapy startproject myspider -
创建爬虫程序
cd myspider —— 进入已创建的scrapy项目
scrapy genspider example example.com —— example为爬虫的名字,example.com为爬取的网站域名 -
设置settings文件
# 是否遵守robots协议(通常设为False)
ROBOTSTXT_OBEY = False
# 最大并发量 默认是16
Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS =32
# 下载延迟为3秒
DOWNLOAD_DELAY = 3
# 请求报头 —— 可增加UA等信息
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
'Accept-Language': 'en',
}
# 爬虫中间件
SPIDER_MIDDLEWARES = {XXX}
# 下载中间件
DOWNLOAD_MIDDLEWARES = {XXX}
# 管道
ITEM_PIPELINES = {XXX}
- 运行程序(两种方式):
- scrapy crawl 爬虫名 —— 终端执行
- 导入模块,用python程序运行scrapy项目
from scrapy import cmdline
cmdline.execute(‘scrapy crawl 爬虫名’.split())
cmdline.execute([‘scrapy’,‘crawl’,‘爬虫名’])
注意:以上两行任选其一即可
数据提取
- 数据提取方法:
通过创建对象使用css或xpath解析方法后的提取方法
方法 | 说明 |
---|---|
extract() | 对结果以列表形式进行返回,如果取不到值则返回空列表 |
extract_first() | 对extract方法返回的结果列表取第一个元素,如果取不到值则返回None |
get() | 等价于extract_first(),get方法为新版推荐方法,如果取不到值则报错 |
getall() | 等价于extract(),getall方法为新版推荐方法,如果取不到值则报错 |
re() | 使用正则表达式提取全部数据 |
re_first() | 使用正则表达式提取re()方法返回的第一个结果 |
css(‘xxx::text’).get() | 提取节点内部的文本 |
css(‘xxx::attr(属性名)’).get() | 提取节点属性名的值 |
Pipeline文件 —— 数据保存
-
settings需要将管道打开(取消注释)
-
Spider内的数据需要传递给管道需要使用yield,不能使用return
-
open_spider() —— 爬虫开始了
-
close_spider() —— 爬虫结束了
-
注意事项:
- Pipeline在设置中的权重越小(字典中的值越小)优先级越高
- Pipeline中process_item方法、open_spider方法和close_spider方法不能修改为其他的名称
- 可获取爬虫的名字
- spider.name
- 可以在item中进行设置(item[xxx]=‘爬虫名’)
# 字典当中的值越小,优先级越高,可以设置多个
ITEM_PIPELINES = {
'practice.pipelines.PracticePipeline': 300,
}
yield关键字 —— 生成器的一种
- 可以节省空间
- 使用灵活
- return在运行之后程序结束,yield在返回之后可以继续执行后续程序
- yield 可以将scrapy.Request对象的链接传递给引擎,引擎将链接传递给调度器
item文件
- 变量 = scrapy.Field() —— 变量不是一个字典对象,Field继承了字典类
- spider文件需要调用item文件
from (path) import (item文件的类)
实例化item文件的类
yield 实例化对象(传递给pipeline)- 实例化item文件的类(两种方式)
- 变量 = item文件的类
变量[‘数据名(item文件的变量名)’] = spider文件传入相关数据的内容 - 变量 = item文件的类(数据名=spider文件传入相关数据的内容),数据名可以传入多个
- 变量 = item文件的类
- 实例化item文件的类(两种方式)
Scrapy Shell
- 需要在终端使用,在未启动spider时去尝试调试代码