Scrapy框架
当爬虫逻辑开始变复杂以后,只靠 requests + 解析器 很快就会越来越乱。
例如:
- 页面很多
- 详情页很多
- 翻页很多
- 数据保存逻辑很多
- 请求流程越来越难维护
这个时候,Scrapy 的价值就体现出来了。它不是“再发一次请求”的工具,而是一套专门为爬虫设计的结构化框架。
本节目标
- 理解 Scrapy 是什么
- 理解为什么需要 Scrapy
- 学会安装 Scrapy
- 学会创建 Scrapy 项目
- 理解项目目录结构
- 理解 Spider、Item、Pipeline、Settings 这些核心概念
- 学会写一个最小 Spider
为什么需要 Scrapy
先想一个情况:
你用 requests 抓一个页面,没问题。
你抓十个页面,也还能忍。
但如果你要抓:
- 列表页
- 列表中的详情页
- 多页分页
- 数据存文件
- 数据存数据库
- 控制请求速度
- 加请求头和 Cookie
如果这些逻辑全都手写在一个脚本里,代码会非常快地失控。
Scrapy 的意义就在于:
- 把请求、解析、存储、配置拆开
- 让爬虫项目更容易维护
Scrapy 是什么
Scrapy 是一个 Python 爬虫框架。
它的核心特点是:
- 结构化
- 可扩展
- 适合中大型爬虫项目
你可以把它理解成:
“专门为爬虫项目搭好的工程骨架”
安装 Scrapy
pip install scrapy安装成功后,可以验证:
scrapy version如果输出版本号,就说明安装成功。
创建项目
scrapy startproject myspider执行后会生成目录结构:
myspider/
scrapy.cfg
myspider/
__init__.py
items.py
middlewares.py
pipelines.py
settings.py
spiders/
__init__.py目录结构怎么理解
scrapy.cfg
项目配置入口文件。
spiders/
这里通常放具体的 Spider,也就是你真正编写抓取逻辑的地方。
items.py
这里通常定义你要抓取的数据结构。
pipelines.py
这里通常处理抓取到的数据,比如:
- 清洗
- 保存
- 写入文件
- 写入数据库
settings.py
这里管理项目配置,例如:
- 并发数
- 延迟时间
- 请求头
- 是否启用某些中间件
middlewares.py
这里通常处理更底层的请求和响应过程,例如:
- 动态请求头
- 代理
- 特殊请求处理
Scrapy 的整体运行流程
你可以先粗略理解成这样:
- Spider 生成请求
- 调度器安排请求顺序
- 下载器去请求页面
- 把响应交还给 Spider
- Spider 解析数据
- 数据交给 Pipeline 处理和保存
你不需要一开始就把每一层都学得很深,但至少要知道 Scrapy 不是“只有一个 spider.py 文件”,而是一个分层结构。
Spider 是什么
Spider 是你真正写抓取逻辑的地方。
它通常负责:
- 指定起始地址
- 接收响应
- 提取数据
- 继续发后续请求
第一个最小 Spider
在 spiders 目录下创建一个文件,例如 quote_spider.py:
import scrapy
class QuoteSpider(scrapy.Spider):
name = "quote"
start_urls = [
"https://quotes.toscrape.com/"
]
def parse(self, response):
title = response.xpath("//title/text()").get()
yield {
"title": title
}逐行理解
class QuoteSpider(scrapy.Spider)
定义一个 Spider 类。
name = "quote"
这个名字就是你后面运行爬虫时要用的名字。
start_urls
表示爬虫启动后首先要访问的地址列表。
parse(self, response)
这是默认解析函数。请求成功后,响应会交给这里处理。
response.xpath(...)
表示用 XPath 从页面里提取数据。
yield {...}
表示把提取到的数据交出去,Scrapy 后面可以继续处理它。
运行 Spider
在项目根目录执行:
scrapy crawl quote这里的 quote 就是你 Spider 里的 name。
如果一切正常,你会看到 Scrapy 开始请求页面并输出抓取结果。
导出结果
Scrapy 很方便的一点是,可以直接导出结果文件。
scrapy crawl quote -o result.json这表示:
- 运行名为
quote的 Spider - 把抓到的数据输出到
result.json
如果提取的是页面标题,最终文件可能像这样:
[
{
"title": "Quotes to Scrape"
}
]Item 是什么
如果抓取字段越来越多,直接 yield 一个普通字典当然也行,但你也可以用 Item 来更规范地定义数据结构。
例如在 items.py 中:
import scrapy
class ArticleItem(scrapy.Item):
title = scrapy.Field()
link = scrapy.Field()这样做的好处是:
- 字段更清晰
- 项目结构更规范
Pipeline 是什么
Spider 负责“抓”,Pipeline 更偏“处理和保存”。
例如:
- 去掉空值
- 清洗字段
- 写入文件
- 写入数据库
一个简单 Pipeline 示例:
class MyspiderPipeline:
def process_item(self, item, spider):
print("收到数据:", item)
return item如果你启用它,每条抓取结果都会先经过这里。
Settings 是什么
settings.py 用来统一配置整个爬虫项目。
例如:
- 请求延迟
- 默认请求头
- 并发数
- 是否开启 Pipeline
这能避免你把配置散落在很多文件里。
Scrapy 和 requests 的区别
requests
更适合:
- 简单页面请求
- 单次接口抓取
- 小型脚本
Scrapy
更适合:
- 多页面抓取
- 大量请求调度
- 结构化项目
- 中大型爬虫工程
所以不是谁替代谁,而是使用场景不同。
一个完整最小流程回顾
你可以把第一个 Scrapy 项目总结成下面几步:
- 安装 Scrapy
- 创建项目
- 在
spiders/下写 Spider - 配置起始地址
- 在
parse()中提取数据 - 用
scrapy crawl运行 - 用
-o导出结果
只要这条主线打通,后面再学 settings、middlewares、pipelines 时就不会悬空。
常见错误
1. Spider 名称和运行命令不一致
如果你的 Spider name 是:
name = "quote"运行命令就应该是:
scrapy crawl quote2. XPath 没选中节点
这时往往不是 Scrapy 不能用,而是提取表达式写错了。
3. 写了 Pipeline 但没启用
Pipeline 不是写完就自动生效,通常还要在 settings.py 中启用。
4. 把所有逻辑都塞进 parse()
零基础阶段先这么写没问题,但随着项目变复杂,要学会拆函数和分层。
练习题
练习 1
新建一个 Scrapy 项目,确保目录结构能正常生成。
练习 2
写一个 Spider,请求一个简单页面,并提取页面标题。
练习 3
把抓到的结果导出到 JSON 文件。
练习 4
尝试定义一个 Item,包含标题和链接两个字段。
练习 5
自己解释一遍:
- Spider 负责什么
- Pipeline 负责什么
- Settings 负责什么
本节小结
Scrapy 的核心价值,不在于“它也能发请求”,而在于它把爬虫项目做成了清晰的工程结构。
你这一节最重要的收获应该是:
- 知道为什么简单脚本不够用了
- 知道 Scrapy 是专门为爬虫设计的框架
- 了解项目目录结构
- 会写一个最基础的 Spider
- 知道 Spider、Item、Pipeline、Settings 分别在解决什么问题
只要这一层建立起来,后面你继续学 settings、中间件、分布式和部署时,就有了清晰主线。