Copyright: Jingmin Wei, Pattern Recognition and Intelligent System, School of Artificial and Intelligence, Huazhong University of Science and Technology
网络爬虫专栏链接
本教程主要参考中国大学慕课的 Python 网络爬虫与信息提取,为个人学习笔记。
在学习过程中遇到了一些问题,都手动记录并且修改更正,保证所有的代码为有效。且结合其他的博客总结了一些常见问题的解决方式。
本教程不商用,仅为学习参考使用。如需转载,请联系本人。
爬虫 MOOC
数据分析 MOOC
廖雪峰老师的 Python 教程
Scrapy 是一个快速功能强大的网络爬虫框架
Win 平台: “以管理员身份运行” cmd ,执行
pip3 install scrapy
pip3 --time-out=2000 install scrapy
安装后小测:执行 scrapy ‐h
Scrapy 不是一个函数功能库,而是一个爬虫框架。
爬虫框架是实现爬虫功能的一个软件结构和功能组件集合,它是一个半成品,能够帮助用户实现专业网络爬虫。
结构,分布式,“5+2”结构
数据流的三个路径:
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
8 Engine 将爬取项发送给 Item Pipeline(框架出口)
9 Engine 将爬取请求发送给 Scheduler
数据流的出入口:
Engine 控制各模块数据流,不间断从 Scheduler 处获得爬取请求,直至请求为空
框架入口:Spider 的初始爬取请求
框架出口:Item Pipeline
Engine
(1) 控制所有模块之间的数据流
(2) 根据条件触发事件
不需要用户修改
Downloader
根据请求下载网页,不需要用户修改
Scheduler
对所有爬取请求进行调度管理,不需要用户修改
Downloader Middleware
目的:实施 Engine、Scheduler 和 Downloader 之间进行用户可配置的控制
功能:修改、丢弃、新增请求或响应
用户可以编写配置代码
Spider
(1) 解析 Downloader 返回的响应(Response)
(2) 产生爬取项(scraped item)
(3) 产生额外的爬取请求(Request)
需要用户编写配置代码
Item Pipelines
(1) 以流水线方式处理 Spider 产生的爬取项
(2) 由一组操作顺序组成,类似流水线,每个操作是一个 Item Pipeline 类型
(3) 可能操作包括:清理、检验和查重爬取项中的 HTML 数据、将数据存储到数据库
需要用户编写配置代码
Spider Middleware
目的:对请求和爬取项的再处理
功能:修改、丢弃、新增请求或爬取项
用户可以编写配置代码
“5+2” 结构
相同点:
两者都可以进行页面请求和爬取,Python 爬虫的两个重要技术路线
两者可用性都好,文档丰富,入门简单
两者都没有处理 js、提交表单、应对验证码等功能(可扩展)
不同点:
页面级爬虫 | 网站级爬虫 |
---|---|
功能库 | 框架 |
并发性考虑不足,性能较差 | 并发性好,性能较高 |
重点在于页面下载 | 重点在于爬虫结构 |
定制灵活 | 一般定制灵活,深度定制困难 |
上手十分简单 | 入门稍难 |
选用哪个技术路线开发爬虫呢?
非常小的需求,requests 库
不太小的需求,Scrapy 框架
定制程度很高的需求(不考虑规模),自搭框架,requests > Scrapy
Scrapy 是为持续运行设计的专业爬虫框架,提供操作的 Scrapy 命令行
Win 下,启动 cmd 控制台
scrapy -h
命令行格式:
scrapy [options] [args]
主要命令在 command 部分编写
命令 | 说明 | 格式 |
---|---|---|
startproject | 创建一个新工程 | scrapy startproject |
genspider | 创建一个爬虫 | scrapy genspider [options] |
settings | 获得爬虫配置信息 | scrapy settings [options] |
crawl | 运行一个爬虫 | scrapy crawl |
list | 列出工程中所有爬虫 | scrapy list |
shell | 启动URL调试命令行 | scrapy shell [url] |
为什么Scrapy采用命令行创建和运行爬虫?
命令行(不是图形界面)更容易自动化,适合脚本控制。本质上,Scrapy是给程序员用的,功能(而不是界面)更重要。
演示HTML页面地址:http://python123.io/ws/demo.html
文件名称:demo.html
应用Scrapy爬虫框架主要是编写配置型代码
选取一个目录(E:\新桌面\python\练习代码\scrapy爬虫框架),然后执行如下命令:
scrapy startproject python123demo
生成工程目录如下:
进入工程目录(E:\新桌面\python\练习代码\scrapy爬虫框架\python123demo),然后执行如下命令:
scrapy genspider demo python123.io
该命令作用:
(1) 生成一个名称为 demo 的 spider
(2) 在 spiders 目录下增加代码文件 demo.py
该命令仅用于生成demo.py,该文件也可以手工生成
配置:(1)初始 URL 地址 (2)获取页面后的解析方式
打开 demo.py
# -*- coding: utf-8 -*-
import scrapy
class DemoSpider(scrapy.Spider): #继承于scrapy.Spider
name = 'demo' #爬虫名字
#allowed_domains = ['python123.io'] #只能爬取该域名以下的链接
#start_urls = ['http://python123.io/'] #要爬取页面的初始页面
start_urls = ['http://python123.io/ws/demo.html'] #上面两行对于这个程序没必要使用
def parse(self, response):
fname = response.url.split('/')[-1] #将response返回的对象存储在文件中
with open(fname, 'wb') as f:
f.write(response.body)
self.log('Save file %s' %fname)
在命令行下(E:\新桌面\python\练习代码\scrapy爬虫框架\python123demo),执行如下命令:
scrapy crawl demo
执行完成后,在工程目录下,生成了demo.html文件
demo.py代码的完整版本:
# -*- coding: utf-8 -*-
import scrapy
class DemoSpider(scrapy.Spider): #继承于scrapy.Spider
name = 'demo' #爬虫名字
def start_requests(self):
urls = ['http://python123.io/ws/demo.html']
for url in urls:
yield scrapy.Request(url = url, callback = self.parse)
#生成器写法,每次调用时才返回一个url链接
def parse(self, response):
fname = response.url.split('/')[-1] #将response返回的对象存储在文件中
with open(fname, 'wb') as f:
f.write(response.body)
self.log('Save file %s' %fname)
由此引入下一节,yield 关键字。
yield 生成器:生成器每次产生一个值(yield 语句),函数被冻结,被唤醒后再产生一个值。
生成器是一个不断产生值的函数。
>>> def gen(n):
for i in range(n):
yield i**2
>>> for i in gen(5):
print(i,"",end="")
0 1 4 9 16
生成器相比一次列出所有内容的优势:
更节省存储空间,响应更迅速,使用更灵活。
步骤1:创建一个工程和 Spider 模板
步骤2:编写 Spider
步骤3:编写 Item Pipeline
步骤4:优化配置策略
Request类
class scrapy.http.Request()
Request 对象表示一个 HTTP 请求。由 Spider 生成,由 Downloader 执行。
属性或方法 | 说明 |
---|---|
.url | Request 对应的请求 URL 地址 |
.method | 对应的请求方法,‘GET’ ‘POST’ 等 |
.headers | 字典类型风格的请求头 |
.body | 请求内容主体,字符串类型 |
.meta | 用户添加的扩展信息,在 Scrapy 内部模块间传递信息使用 |
.copy() | 复制该请求 |
Response类
class scrapy.http.Response()
Response 对象表示一个 HTTP 响应。由 Downloader 生成,由 Spider 处理。
属性或方法 | 说明 |
---|---|
.url | Response 对应的 URL 地址 |
.status | HTTP 状态码,默认是 200 |
.headers | Response 对应的头部信息 |
.body | Response 对应的内容信息,字符串类型 |
.flags | 一组标记 |
.request | 产生 Response 类型对应的 Request 对象 |
.copy() | 复制该响应 |
Item类
class scrapy.item.Item()
Item 对象表示一个从 HTML 页面中提取的信息内容。由 Spider 生成,由 Item Pipeline 处理。
Item 类似字典类型,可以按照字典类型操作。
Scrapy爬虫支持多种HTML信息提取方法:
CSS Selector的基本使用
<HTML>.css('a::attr(href)').extract()