Scrapy 不是一个函数功能库,而是一个爬虫框架
官网:https://scrapy.org/
中文文档:https://scrapy-chs.readthedocs.io/zh_CN/0.24/index.html
安装
1 | pip3 install scrapy |
命令行测试
1 | scrapy ‐h |
框架结构
1、Engine 从 Spider 处获得爬取请求 (Request)
2、Engine 将爬取请求转发给 Scheduler,用于调度
3、Engine 从 Scheduler 处获得下一个要爬取的请求
4、Engine 将爬取请求通过中间件发送给 Downloader
5、爬取网页后,Downloader 形成响应(Response),通过中间件发给 Engine
6、Engine 将收到的响应通过中间件发送给 Spider 处理
7、Spider 处理响应后产生爬取项(scraped Item)和新的爬取请求(Requests)给Engine
数据流的出入口
Engine 控制各模块数据流,不间断从 Scheduler 处获得爬取请求,直至请求为空
框架入口:Spider 的初始爬取请求
框架出口:Item Pipeline
框架解析
Engine
- 控制所有模块之间的数据流
- 根据条件触发事件
- 不需要用户修改
Downloader
- 根据请求下载网页
- 不需要用户修改
Downloader Middleware
- 目的:实施 Engine、Scheduler 和 Downloader 之间进行用户可配置的控制
- 功能:修改、丢弃、新增请求或响应
- 用户可以编写配置代码
Scheduler
- 对所有爬取请求进行调度管理
- 不需要用户修改
Spider
- 解析 Downloader 返回的响应(Response)
- 产生爬取项(scraped item)
- 产生额外的爬取请求(Request)
- 需要用户编写配置代码
Spider Middleware
- 目的:对请求和爬取项的再处理
- 功能:修改、丢弃、新增请求或爬取项
- 用户可以编写配置代码
Item Pipelines
- 以流水线方式处理 Spider 产生的爬取项
- 由一组操作顺序组成,类似流水线,每个操作是一个Item Pipeline 类型
- 可能操作包括:清理、检验和查重爬取项中的 HTML 数据、将数据存储到数据库
- 需要用户编写配置代码
requests vs Scrapy
requests | scrapy |
---|---|
页面级爬虫 | 网站级爬虫 |
功能库 | 框架 |
并发性考虑不足,性能较差 | 并发性好,性能较高 |
重点在于页面下载 | 重点在于爬虫结构 |
定制灵活 | 一般定制灵活,深度定制困难 |
上手十分简单 | 入门稍难 |
Scrapy 爬虫的常用命令
Scrapy 是为持续运行设计的专业爬虫框架,提供操作的是 Scrapy 命令行
1 | scrapy <command> [options] [args] |
命令 | 说明 | 格式 |
---|---|---|
startproject | 创建一个新工程 | scrapy startproject “name” [dir] |
genspider | 创建一个爬虫 | scrapy genspider [options] “name” “domain” |
settings | 获得爬虫配置信息 | scrapy settings [options] |
crawl | 运行一个爬虫 | scrapy crawl “spider” |
list | 列出工程中所有爬虫 | scrapy list |
shell | 启动URL调试命令行 | scrapy shell [url] |
Scrapy 爬虫简单实例
演示的 HTML 页面地址:https://python123.io/ws/demo.html
步骤1:新建一个 Scrapy 爬虫工程
选择一个目录,执行如下命令
1 | scrapy startproject scrapy_demo |
生成的工程目录
1 | scrapy_demo --> 外层目录 |
步骤2:在工程中产生一个 Scrapy 爬虫
进入工程目录(scrapy_demo),执行如下命令
1 | scrapy genspider demo python123.io |
该命令作用:
- 生成一个名称为 demo 的 spider
- 在 spiders 目录下增加代码文件 demo.py
- 该命令仅用于生成 demo.py,该文件也可以手工生成
生成的 demo.py 文件
1 | # -*- coding: utf-8 -*- |
步骤3:配置产生的 spider 爬虫
- 初始 URL 地址
- 获取页面后的解析方式
1 | # -*- coding: utf-8 -*- |
步骤4:运行爬虫,获取网页
执行如下命令
1 | scrapy crawl demo |
在工程目录(scrapy_demo)下,就可以看到 demo.html 文件
demo.py 文件代码的完整版本
1 | # -*- coding: utf-8 -*- |
yield 关键字
包含 yield 语句的函数是一个生成器
生成器每次产生一个值(yield 语句),函数被冻结,被唤醒后再产生一个值
生成器是一个不断产生值的函数
1 | def gen(n): |
生成器的优势
- 更节省存储空间
- 响应更迅速
- 使用更灵活
Scrapy 爬虫的数据类型
Request (scrapy.http.Request)
Request 对象表示一个 HTTP 请求由 Spider 生成,由 Downloader 执行
属性或方法 | 说明 |
---|---|
.url | Request 对应的请求 URL 地址 |
.method | 对应的请求方法,’GET’ ‘POST’等 |
.headers | 字典类型风格的请求头 |
.body | 请求内容主体,字符串类型 |
.meta | 用户添加的扩展信息,在 Scrapy 内部模块间传递信息使用 |
.copy() | 复制该请求 |
Response (scrapy.http.Response)
Response 对象表示一个HTTP响应,由 Downloader 生成,由 Spider 处理
属性或方法 | 说明 |
---|---|
.url | Response 对应的 URL 地址 |
.status | HTTP 状态码,默认是 200 |
.headers | Response 对应的头部信息 |
.body | Response 对应的内容信息,字符串类型 |
.flags | 一组标记 |
.request | 产生 Response 类型对应的 Request 对象 |
.copy() | 复制该响应 |
Item (scrapy.item.Item)
Item 对象表示一个从 HTML 页面中提取的信息内容,由 Spider 生成,由 Item Pipeline 处理
Item 类似字典类型,可以按照字典类型操作
Scrapy 爬虫提取信息的方法
Scrapy 爬虫支持多种 HTML 信息提取方法:
- Beautiful Soup
- lxml
- re
- XPath Selector
- CSS Selector
CSS Selector 的基本使用
1 | <HTML>.css('a::attr(href)').extract() |
股票数据 Scrapy 爬虫实例
获取股票列表:
东方财富网:http://quote.eastmoney.com/stocklist.html
获取个股信息:
百度股票:https://gupiao.baidu.com/stock/
单个股票:https://gupiao.baidu.com/stock/sz002439.html
编写 spider 处理链接爬取和页面解析,编写 pipelines 处理信息存储
步骤1:建立工程和 Spider 模板
依次执行如下命令
1 | scrapy startproject BaiduStocks |
步骤2:编写 Spider
配置 stocks.py 文件
修改对返回页面的处理
修改对新增 URL 爬取请求的处理
1 | # -*- coding: utf-8 -*- |
步骤3:编写 ITEM Pipelines
配置 pipelines.py 文件
定义对爬取项(Scraped Item)的处理类
配置 ITEM_PIPELINES 选项
1 | # -*- coding: utf-8 -*- |
配置 ITEM_PIPELINES 选项
配置 settings.py 文件
1 | # Configure item pipelines |
可选配置并发连接选项
settings.py 文件中
选项 | 说明 |
---|---|
CONCURRENT_REQUESTS | Downloader 最大并发请求下载数量,默认 32 |
CONCURRENT_ITEMS | Item Pipeline 最大并发ITEM处理数量,默认100 |
CONCURRENT_REQUESTS_PER_DOMAIN | 每个目标域名最大的并发请求数量,默认 8 |
CONCURRENT_REQUESTS_PER_IP | 每个目标 IP 最大的并发请求数量,默认 0,非 0 有效 |
执行程序
1 | scrapy crawl stocks |