
本文详解Scrapy中response.follow()的正确用法,通过分离页面导航与数据解析逻辑,解决“能翻页但不返回数据”的常见问题,并以FIFA Index球员数据抓取为例,提供可运行的结构化代码方案。
本文详解scrapy中`response.follow()`的正确用法,通过分离页面导航与数据解析逻辑,解决“能翻页但不返回数据”的常见问题,并以fifa index球员数据抓取为例,提供可运行的结构化代码方案。
在使用Scrapy进行多层级网页抓取时,一个典型误区是将链接遍历(navigation)与数据提取(extraction)混在同一解析方法中——这正是原代码无法返回任何数据的根本原因。原parse()方法试图在列表页中直接提取球员详情页的数据,但此时response对象仍指向列表页HTML,其CSS选择器自然无法命中详情页的h5.card-header或span.data-units等元素,导致.get()始终返回None。
正确的做法是遵循Scrapy的职责分离原则:
- parse() 负责发现并调度新请求(如球员详情页URL、下一页URL);
- 专用解析方法(如parse_player())负责处理响应并提取数据,该方法接收的是目标详情页的完整response对象。
以下是修正后的完整、可运行的Scrapy Spider代码:
import scrapy
class FifaIndexPlayerSpider(scrapy.Spider):
name = "fifa_players"
allowed_domains = ["fifaindex.com"]
def start_requests(self):
# 使用原始URL(注意:&需为&,非&)
url = "https://www.fifaindex.com/players/?gender=0&league=13&order=desc"
yield scrapy.Request(url, callback=self.parse)
def parse(self, response):
# ✅ 步骤1:提取当前页所有球员详情页链接
player_links = response.css("figure.player a::attr(href)").getall()
for link in player_links:
# ✅ 步骤2:使用 response.follow() 并指定专属回调函数
yield response.follow(link, callback=self.parse_player)
# ✅ 步骤3:提取并跟进“下一页”链接(支持分页)
next_page = response.css("li.ml-auto a::attr(href)").get()
if next_page:
yield response.follow(next_page, callback=self.parse)
def parse_player(self, response):
# ✅ 此处 response 已是球员详情页,可安全提取
name = response.css("h5.card-header::text").get()
# 注意:weight 元素可能有多个,示例中取索引1(需根据实际HTML结构调整)
weight_elements = response.css("span.data-units.data-units-metric::text").getall()
weight = weight_elements[1] if len(weight_elements) > 1 else None
yield {
"name": name.strip() if name else None,
"weight": weight.strip() if weight else None,
"url": response.url # 可选:记录来源URL便于调试
}关键要点说明:
- response.follow() 的本质:它是 scrapy.Request 的便捷封装,自动继承Referer头、处理相对路径,并将目标响应传递给指定的callback函数。它不执行解析,仅发起请求。
- 避免在列表页解析详情页数据:原代码中response.css("h5.card-header::text").get()在列表页执行,必然失败。必须确保解析逻辑位于处理目标页面的回调中。
- CSS选择器健壮性:span.data-units.data-units-metric 中的类名需严格匹配(中间用.连接,非空格)。若页面结构变化,建议先用浏览器开发者工具验证选择器有效性。
- 容错处理:添加.strip()和None检查,防止空白字符或缺失字段导致Pipeline报错。
- 域名限制:设置allowed_domains = ["fifaindex.com"]可防止爬虫意外跳转至外部站点。
运行与导出:
启动爬虫并导出CSV:
scrapy crawl fifa_players -o players.csv
生成的players.csv将包含结构化姓名与体重数据,可直接用于分析或导入数据库。
⚠️ 注意事项:
- FIFA Index网站可能有反爬机制(如User-Agent检测、频率限制),生产环境建议在settings.py中配置USER_AGENT、DOWNLOAD_DELAY及ROBOTSTXT_OBEY = False;
- 若遇到403 Forbidden,需添加合法请求头(如'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)');
- 遵守robots.txt及网站Terms of Service,合理控制爬取速率,尊重数据版权。
掌握这一“导航-解析”分离模式,是构建健壮Scrapy爬虫的核心基础——它让代码逻辑清晰、易于调试、便于扩展(例如后续增加身高、俱乐部等字段,只需修改parse_player即可)。


















