Scrapy实战
真正做项目时,你不会只写一个 Spider 文件就结束。
你会逐渐遇到这些更真实的问题:
- 页面是动态渲染的
- 请求必须带特定头信息
- 某些接口是 POST 请求
- 不同请求要带不同 Cookie
- 部分逻辑要在请求发出前或响应回来后插入处理
这时候,你就会开始从“会用 Scrapy”进入“会做 Scrapy 项目”的阶段。
本节目标
- 理解 Scrapy 实战中常见的真实问题
- 理解中间件的作用
- 理解 Selenium 在动态页面中的定位
- 学会给请求增加请求头和 Cookie
- 理解随机请求头和 POST 抓取的基本思路
实战和教程例子的区别
教程里你经常会看到:
- 一个起始地址
- 一个 XPath
- 一次请求
- 一次输出
但真实项目往往不是这样。你真正面对的页面通常更复杂:
- 数据不一定直接在 HTML 里
- 页面不一定一次请求就拿全
- 请求不一定是 GET
- 返回不一定总是稳定
所以实战阶段最重要的,不是记更多 API,而是学会分析请求链路和处理复杂情况。
中间件是什么
Scrapy 中间件可以理解成:
- 在请求发出去之前插入处理逻辑
- 在响应回来之后插入处理逻辑
它常见用途包括:
- 动态加请求头
- 动态加 Cookie
- 设置代理
- 和 Selenium 配合
为什么中间件重要
因为有很多操作并不适合直接写死在 Spider 里。
例如:
- 每次请求都要加同一个头
- 不同请求要切换不同 User-Agent
- 要统一处理某类响应
如果这些都塞进 Spider,代码会很快变乱。
添加请求头
你可以在单个请求中直接写:
yield scrapy.Request(
url="https://example.com",
headers={
"User-Agent": "Mozilla/5.0"
}
)这适合简单场景。
如果项目里大量请求都需要统一处理,更常见的方式是放进中间件或 settings。
添加 Cookie
有些页面依赖登录状态或会话信息。
yield scrapy.Request(
url="https://example.com/profile",
cookies={
"sessionid": "abc123"
}
)如果 Cookie 不对,返回内容很可能不是你真正想要的页面。
随机请求头
很多网站会根据请求头判断访问行为是否异常。
如果所有请求的 User-Agent 都完全一样,而且访问频率还很高,就更容易暴露机器特征。
一个基础思路是准备一组 User-Agent:
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
"Mozilla/5.0 (X11; Linux x86_64)"
]然后随机取一个给请求使用。
Selenium 的定位
有些页面的数据严重依赖 JavaScript 渲染。
这时你直接请求原始 HTML,可能只能拿到一个空壳页面。
比如页面源码里几乎没有真正数据,但浏览器打开后内容却很多,这往往说明:
- 页面数据是后续异步请求加载的
- 或者页面依赖浏览器执行 JavaScript
这时候 Selenium 的价值就出现了。
你可以把 Selenium 理解成:
- 让程序去控制一个浏览器
它比普通请求更重,但在动态页面场景中很有用。
POST 请求在实战中的意义
很多初学者会下意识认为爬虫就是 GET 请求,其实不是。
很多接口:
- 登录接口
- 搜索接口
- 分页接口
- 提交型接口
都可能是 POST。
Scrapy 中写 POST 请求的基础方式是:
yield scrapy.FormRequest(
url="https://example.com/login",
formdata={
"username": "tom",
"password": "123456"
},
callback=self.parse_login
)这表示:
- 发起 POST 表单请求
- 带上表单参数
- 请求完成后交给
parse_login处理
一个更贴近实战的流程示例
假设你要抓一个登录后可见的课程列表页面,思路可能是:
- 先分析登录请求是不是 POST
- 确认用户名、密码参数名是什么
- 发登录请求
- 拿到登录成功后的状态
- 再访问课程列表页面
- 解析课程标题和链接
这已经不是“抓一个静态页”的难度了,但思路是连贯的。
中间件 + 请求头的一个简单思路
假设你想让每个请求都自动带上一个浏览器标识,可以在中间件中统一处理。
你不用现在就把完整中间件细节全背下来,但至少要知道:
- 某些共用逻辑适合放中间件
- 中间件能让 Spider 更专注于抓取逻辑本身
实战中的真正重点
很多人以为实战的重点是“记住更多框架用法”,其实不是。
真正重点是:
- 请求该在哪里发
- 响应该在哪里解析
- 数据该在哪里保存
- 哪些逻辑是单个请求的
- 哪些逻辑应该抽到全局配置或中间件
这是项目意识,而不是 API 背诵。
常见错误
1. 页面抓不到,就立刻怀疑 XPath
其实更常见的真实原因可能是:
- 页面是动态加载的
- 请求头不对
- Cookie 丢了
- 应该 POST 却写成了 GET
2. 把所有逻辑都堆在 parse()
这会导致代码很快失控。
3. 用 Selenium 解决一切问题
Selenium 很强,但也很重。能直接抓接口,就不要上浏览器自动化。
4. 没先分析请求过程就开始写代码
正确顺序应该是:
先观察浏览器行为,再决定 Scrapy 应该怎么写。
练习题
练习 1
写一个 Scrapy 请求,手动加上 User-Agent。
练习 2
写一个带 Cookie 的请求,思考它适用于什么场景。
练习 3
尝试写一个 FormRequest,模拟最简单的 POST 请求。
练习 4
找一个动态页面,观察它是不是先加载 HTML 再请求接口。
练习 5
自己总结:哪些逻辑适合写在 Spider 中,哪些逻辑更适合写在中间件或配置里。
本节小结
Scrapy 实战阶段最重要的,不是学会更多命令,而是开始理解真实抓取项目中问题会出现在哪里。
你这一节最重要的收获应该是:
- 知道中间件是干什么的
- 知道 Selenium 为什么会出现
- 知道请求头、Cookie、POST 在实战里为什么重要
- 开始建立“请求、解析、保存、配置分层”的意识
只要这层意识建立起来,你就不再只是会写例子,而是开始接近真正的爬虫项目开发。