S
Scrapy库知识点大全
编程小白也能看懂的Python爬虫框架详解
Scrapy是什么?
Scrapy是一个强大的Python爬虫框架,专门用于从网站上爬取结构化数据。你可以把它想象成一个”网络收割机”,自动浏览网页、采集信息并整理成你需要的格式。
为什么选择Scrapy?
- 高效快捷:内置异步处理机制,比普通爬虫快很多
- 功能全面:自动处理请求、响应、下载、数据提取全套流程
- 扩展性强:通过中间件可以灵活扩展功能
- 成熟稳定:经过多年发展,有强大的社区支持
💡 大白话解释:Scrapy就像是爬虫界的”自动化工厂”,你只需要告诉它要什么产品(数据)、去哪里拿(网址),它就能自动完成整个生产过程!
Scrapy架构图解
理解Scrapy的工作原理非常重要,下面是它的核心组件和工作流程:
引擎(Engine) – 整个框架的”大脑”,控制数据流
调度器(Scheduler) – 管理请求队列,决定下一个请求
下载器(Downloader) – 实际发送请求和接收响应
爬虫(Spiders) – 你编写的代码,定义如何爬取和数据提取
项目管道(Item Pipeline) – 数据处理和存储
中间件(Middlewares) – 扩展功能的钩子
工作流程:引擎获取初始请求 → 调度器排队 → 下载器获取网页 → 爬虫解析 → 提取的数据到管道 → 存储结果
安装Scrapy
Scrapy的安装非常简单,只需要一条命令:
pip install scrapy
安装完成后,可以通过以下命令验证是否安装成功:
scrapy version
常见安装问题
- Windows用户:可能需要安装Microsoft Visual C++ Build Tools
- Mac/Linux用户:通常直接安装即可
- 如果遇到权限问题,可以添加–user参数
创建Scrapy项目
使用Scrapy命令行工具创建项目骨架:
scrapy startproject myproject
这个命令会创建一个名为myproject的文件夹,包含以下结构:
myproject/
├── scrapy.cfg # 项目配置文件
└── myproject/ # 项目Python模块
├── __init__.py
├── items.py # 定义数据模型
├── middlewares.py # 中间件定义
├── pipelines.py # 数据处理管道
├── settings.py # 项目设置
└── spiders/ # 爬虫目录
└── __init__.py
├── scrapy.cfg # 项目配置文件
└── myproject/ # 项目Python模块
├── __init__.py
├── items.py # 定义数据模型
├── middlewares.py # 中间件定义
├── pipelines.py # 数据处理管道
├── settings.py # 项目设置
└── spiders/ # 爬虫目录
└── __init__.py
💡 理解项目结构:这个结构就像是你的”爬虫工厂”的车间布局,每个文件负责不同的功能,协同工作完成爬取任务。
编写你的第一个爬虫
在spiders目录中创建Python文件,定义一个Spider类:
import scrapy
class MySpider(scrapy.Spider):
# 爬虫的唯一标识名
name = ‘myspider’
# 起始URL列表
start_urls = [
‘http://example.com/page1’,
‘http://example.com/page2’
]
# 处理响应的方法
def parse(self, response):
# 提取数据并返回Items或Requests
title = response.css(‘h1::text’).get()
yield {
‘title’: title,
‘url’: response.url
}
class MySpider(scrapy.Spider):
# 爬虫的唯一标识名
name = ‘myspider’
# 起始URL列表
start_urls = [
‘http://example.com/page1’,
‘http://example.com/page2’
]
# 处理响应的方法
def parse(self, response):
# 提取数据并返回Items或Requests
title = response.css(‘h1::text’).get()
yield {
‘title’: title,
‘url’: response.url
}
核心组件详解
- name:爬虫的唯一标识,必须唯一
- start_urls:爬虫开始抓取的网址列表
- parse():默认的回调方法,处理响应并提取数据
- response:包含下载的网页内容,可以用CSS或XPath选择器提取数据
数据提取技巧
Scrapy提供了两种强大的选择器:CSS和XPath
CSS选择器示例
# 提取标题文本
response.css(‘title::text’).get()
# 提取所有链接的href属性
response.css(‘a::attr(href)’).getall()
# 提取文章内容
response.css(‘div.article-content p::text’).getall()
response.css(‘title::text’).get()
# 提取所有链接的href属性
response.css(‘a::attr(href)’).getall()
# 提取文章内容
response.css(‘div.article-content p::text’).getall()
XPath选择器示例
# 提取标题文本
response.xpath(‘//title/text()’).get()
# 提取具有class=”price”的span元素
response.xpath(‘//span[@class=”price”]/text()’).get()
# 提取相对路径示例
divs = response.xpath(‘//div’)
for d in divs:
d.xpath(‘.//p’) # 注意开头的点号
response.xpath(‘//title/text()’).get()
# 提取具有class=”price”的span元素
response.xpath(‘//span[@class=”price”]/text()’).get()
# 提取相对路径示例
divs = response.xpath(‘//div’)
for d in divs:
d.xpath(‘.//p’) # 注意开头的点号
💡 选择器使用技巧:CSS选择器更简洁易读,适合简单场景;XPath更强大灵活,适合复杂文档结构。实际开发中可以根据需要使用混合方式。
数据处理管道(Item Pipeline)
管道负责处理爬虫提取的数据,常见用途:
- 清洗数据(如去除空白、格式化)
- 验证数据(检查字段是否完整)
- 去重(避免重复数据)
- 存储数据(保存到文件、数据库)
创建管道示例
1. 在items.py中定义Item
import scrapy
class ProductItem(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
url = scrapy.Field()
class ProductItem(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
url = scrapy.Field()
2. 在pipelines.py中创建管道
class JsonWriterPipeline:
def open_spider(self, spider):
self.file = open(‘products.json’, ‘w’)
def close_spider(self, spider):
self.file.close()
def process_item(self, item, spider):
line = json.dumps(dict(item)) + “\n”
self.file.write(line)
return item
def open_spider(self, spider):
self.file = open(‘products.json’, ‘w’)
def close_spider(self, spider):
self.file.close()
def process_item(self, item, spider):
line = json.dumps(dict(item)) + “\n”
self.file.write(line)
return item
3. 在settings.py中启用管道
ITEM_PIPELINES = {
‘myproject.pipelines.JsonWriterPipeline’: 300,
}
‘myproject.pipelines.JsonWriterPipeline’: 300,
}
中间件(Middleware)
中间件是Scrapy的”插件系统”,允许你全局修改请求和响应
下载器中间件示例
添加自定义User-Agent:
class CustomUserAgentMiddleware:
def process_request(self, request, spider):
request.headers[‘User-Agent’] = ‘MyCustomAgent/1.0’
return None
def process_request(self, request, spider):
request.headers[‘User-Agent’] = ‘MyCustomAgent/1.0’
return None
Spider中间件示例
处理爬虫输出的Items:
class ItemCountMiddleware:
def __init__(self):
self.item_count = 0
def process_spider_output(self, response, result, spider):
for item in result:
if isinstance(item, scrapy.Item):
self.item_count += 1
spider.logger.info(f”已抓取 {self.item_count} 个商品”)
yield item
def __init__(self):
self.item_count = 0
def process_spider_output(self, response, result, spider):
for item in result:
if isinstance(item, scrapy.Item):
self.item_count += 1
spider.logger.info(f”已抓取 {self.item_count} 个商品”)
yield item
💡 中间件使用场景:更换IP代理、自动重试失败请求、添加自定义HTTP头、处理异常、统计爬取指标等高级功能。
Scrapy快速参考
常用命令
- 创建项目:
scrapy startproject 项目名 - 创建爬虫:
scrapy genspider 爬虫名 域名 - 运行爬虫:
scrapy crawl 爬虫名 - 交互式shell:
scrapy shell URL - 导出数据:
scrapy crawl 爬虫名 -o 输出文件.json
选择器速查
- CSS提取文本:
selector::text - CSS提取属性:
selector::attr(属性名) - XPath提取文本:
/text() - XPath提取属性:
/@属性名
调试技巧
- -s CLOSESPIDER_ITEMCOUNT=100
只抓取100个items后停止 - –nolog
关闭日志输出 - –loglevel INFO
控制日志级别 - scrapy shell URL
调试页面解析
学习资源
- 官方文档:
docs.scrapy.org - Scrapy教程:
scrapy.org/doc/topics - GitHub示例:
github.com/scrapy/quotesbot - 中文社区:
scrapy-chs.readthedocs.io