Scrapy
简介
Scrapy 是一个为了爬取网站数据, 提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘, 信息处理或存储历史数据等一系列的程序中.
其最初是为了 页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取 API 所返回的数据(例如 Amazon Associates web Services ) 或者通用的网络爬虫.
各组件作用
Scrapy Engine
引擎负责控制数据流在系统中所有组件中流动, 并在相应动作发生时触发事件. 详细内容查看下面的数据流 (Data Flow) 部分.
调度器(Scheduler)
调度器从引擎接受 request 并将他们入队, 以便之后引擎请求他们时提供给引擎.
初始的爬取 URL 和后续在页面中获取的待爬取的 URL 将放入调度器中, 等待爬取. 同时调度器会自动去除重复的 URL(如果特定的 URL 不需要去重也可以通过设置实现, 如 post 请求的 URL)下载器(Downloader)
下载器负责获取页面数据并提供给引擎, 而后提供给 spider.
Spiders
Spider 是 Scrapy 用户编写用于分析 response 并提取 item(即获取到的 item)或额外跟进的 URL 的类. 每个 spider 负责处理一个特定 (或一些) 网站
Item Pipeline
Item Pipeline 负责处理被 spider 提取出来的 item. 典型的处理有清理, 验证及持久化(例如存取到数据库中)
当页面被爬虫解析所需的数据存入 Item 后, 将被发送到项目管道(Pipeline), 并经过几个特定的次序处理数据, 最后存入本地文件或存入数据库
下载器中间件(Downloader middlewares)
下载器中间件是在引擎及下载器之间的特定钩子(specific hook), 处理 Downloader 传递给引擎的 response. 其提供了一个简便的机制, 通过插入自定义代码来扩展 Scrapy 功能.
Spider 中间件(Spider middlewares)
Spider 中间件是在引擎及 Spider 之间的特定钩子 (specific hook), 处理 spider 的输入(response) 和输出(items 及 requests). 其提供了一个简便的机制, 通过插入自定义代码来扩展 Scrapy 功能.
数据流(Data flow)
引擎打开一个网站(open a domain), 找到处理该网站的 Spider 并向该 spider 请求第一个要爬取的 URL(s).
引擎从 Spider 中获取到第一个要爬取的 URL 并在调度器 (Scheduler) 以 Request 调度.
引擎向调度器请求下一个要爬取的 URL.
调度器返回下一个要爬取的 URL 给引擎, 引擎将 URL 通过下载中间件 (请求(request) 方向)转发给下载器(Downloader).
一旦页面下载完毕, 下载器生成一个该页面的 Response, 并将其通过下载中间件 (返回(response) 方向)发送给引擎.
引擎从下载器中接收到 Response 并通过 Spider 中间件 (输入方向) 发送给 Spider 处理.
Spider 处理 Response 并返回爬取到的 Item 及 (跟进的) 新的 Request 给引擎.
引擎将 (Spider 返回的) 爬取到的 Item 给 Item Pipeline, 将(Spider 返回的)Request 给调度器.
(从第二步)重复直到调度器中没有更多地 request, 引擎关闭该网站.
开始第一个爬虫
工具和环境
语言: python 3.7
IDE: Pycharm
浏览器: Chrome
爬虫框架: Scrapy 1.5.2
下载 pip 包
pip install scrapy
图片. PNG
创建 scrapy 项目
# 选择要在哪个目录下创建爬虫项目
scrapy startproject 项目名
图片. PNG
使用 PyCharm 打开项目后文件结构如下
图片. PNG
* scrapy.cfg: 项目的配置文件
* test/: 项目的 Python 模块, 将会从这里引用代码
* test/items.py: 项目的目标文件
* test/pipelines.py: 项目的管道文件
* test/settings.py: 项目的设置文件
* test/spiders/: 存储爬虫代码目录
创建一个名为 book 的爬虫, 指定爬取域的范围
- # scrapy genspider 爬虫名 "爬虫范围"
- scrapy genspider book "dangdang.com"
图片. PNG
图片. PNG
也可以由我们自行创建 book.py 并编写上面的代码, 只不过使用命令可以免去编写固定代码的麻烦要建立一个 Spider, 你必须用 scrapy.Spider 类创建一个子类, 并确定了三个强制的属性 和 一个方法
name = "" : 这个爬虫的识别名称, 必须是唯一的, 在不同的爬虫必须定义不同的名字
allow_domains = [] 是搜索的域名范围, 也就是爬虫的约束区域, 规定爬虫只爬取这个域名下的网页, 不存在的 URL 会被忽略
start_urls = () : 爬取的 URL 元祖 / 列表. 爬虫从这里开始抓取数据, 所以, 第一次下载的数据将会从这些 urls 开始. 其他子 URL 将会从这些起始 URL 中继承性生成
parse(self, response) : 解析的方法, 每个初始 URL 完成下载后将被调用, 调用的时候传入从每一个 URL 传回的 Response 对象来作为唯一参数, 主要作用如下:
负责解析返回的网页数据 (response.body), 提取结构化数据(生成 item) 生成需要下一页的 URL 请求
爬去数据
编写代码
- class BookSpider(scrapy.Spider):
- name = 'book'
- allowed\_domains = ['dangdang.com']
- start\_urls = ['http://category.dangdang.com/pg1-cp01.54.92.01.00.00.html'] # 修改 url 爬去指定类别书籍
- # response 为以请求后响应结果
- def parse(self, response):
- # 使用 Xpath 获取内容
- for each in response.xpath('//\*[@id="component\_59"]/li'):
- # extract() 获取文本内容
- title = each.xpath("p[1]/a/text()").extract() # 获取数据标题
- price = each.xpath("p[3]/span[1]/text()").extract() # 获取价格
- star = each.xpath("p[4]/a/text()").extract() # 获取评分
- detail = each.xpath("p[2]/text()").extract() # 获取描述信息
- if not detail:
- detail = ["本书暂无 detail,,,,,,"]
- print('detail', detail)
- print("title", title)
- print('price', price)
- print('star', star)
- response
图片. PNG
执行爬虫
- # scrapy crawl 爬虫名
- scrapy crawl book
图片. PNG
结果
图片. PNG
补充
项目 (Project-only) 命令
crawl: 使用 spider 进行爬取.
scrapy crawl myspider
check: 运行 contract 检查.
scrapy check -l
list: 列出当前项目中所有可用的 spider. 每行输出一个 spider.
edit
parse: 获取给定的 URL 并使用相应的 spider 分析处理. 如果您提供 --callback 选项, 则使用 spider 的该方法处理, 否则使用 parse .
--spider=SPIDER: 跳过自动检测 spider 并强制使用特定的 spider
--a NAME=VALUE: 设置 spider 的参数(可能被重复)
--callback or -c: spider 中用于解析返回 (response) 的回调函数
--pipelines: 在 pipeline 中处理 item
--rules or -r: 使用 CrawlSpider 规则来发现用来解析返回 (response) 的回调函数
--noitems: 不显示爬取到的 item
--nolinks: 不显示提取到的链接
--nocolour: 避免使用 pygments 对输出着色
--depth or -d: 指定跟进链接请求的层次数(默认: 1)
--verbose or -v: 显示每个请求的详细信息
scrapy parse http://www.example.com/ -c parse_item
genspider: 在当前项目中创建 spider
- scrapy genspider [-t template] <name> <domain>
- scrapy genspider -t basic example example.com
deploy: 将项目部署到 Scrapyd 服务
bench: 运行 benchmark 测试
参考资料
- https://www.cnblogs.com/cutd/p/6208861.html
- http://www.runoob.com/w3cnote/scrapy-detail.html
来源: https://www.qcloud.com/developer/article/1405585