
在 scrapy 爬虫中,若需提取整个页面共有的静态信息(如赛程距离),应避免在循环内重复定位;正确做法是在解析函数开头统一提取一次,并在遍历每条记录时复用该值。
在 scrapy 爬虫中,若需提取整个页面共有的静态信息(如赛程距离),应避免在循环内重复定位;正确做法是在解析函数开头统一提取一次,并在遍历每条记录时复用该值。
当爬取赛马/灵缇赛事页面(例如 https://www.php.cn/link/0910e6e5e6ebebf9a19cd0df422b6b36)时, ✅ 正确解法:在循环外一次性提取,再注入每条数据项 推荐使用更简洁、可读性更强的 CSS 选择器(也可继续用 XPath): ⚠️ 注意事项: 总结:将「页面上下文信息」(如赛事距离、场地名称、日期、场次编号等)与「行级明细数据」(如每只灵缇的名次、时间、 trainer)在逻辑上分层处理,是构建健壮、可维护 Scrapy 爬虫的关键设计原则。distance(如 "OPEN 520m")属于页面级元信息——它对当前赛程下所有参赛犬只均相同,而非每个 行内独立存在。因此,若在 for div in divs: 循环内部使用 div.xpath(...) 查找距离,XPath 会局限在当前 节点范围内搜索,而目标元素( .race-header__info__grade)实际位于页面顶部的 或 def parse(self, response):
# ✅ 在循环前提取页面级字段:距离
distance = response.css(".race-header__info__grade::text").get()
# 若需清洗(如仅保留数字部分),可追加处理:
# import re
# distance_m = re.search(r'(\d+)m', distance)
# distance = distance_m.group(1) if distance_m else None
# 定位所有参赛犬记录行
runner_rows = response.xpath('//tr[@class="accordion__anchor race-runner"]')
for row in runner_rows:
yield {
'distance': distance, # 复用单次提取结果
'grade': row.xpath(".//td[@class='race-runners__grade']/text()").getall(),
'greyhound': row.xpath('./td[3]/div[1]/a/text()').getall(),
'position': row.xpath('./td[1]/text()').getall(),
'trainer': row.xpath(".//div[@class='race-runners__name__trainer']/a/text()").getall(),
'weight': row.xpath(".//td[@class='race-runners__weight']/text()").getall(),
'first_sec': row.xpath(".//td[@class='race-runners__sectional']/text()").get(),
'second_sec': row.xpath(".//td[@class='race-runners__sectional'][2]/text()").getall(),
'time': row.xpath(".//td[@class='race-runners__time']/text()").getall(),
'margin': row.xpath(".//td[@class='race-runners__margin']/text()").getall(),
'starting_price': row.xpath(".//td[@class='race-runners__starting-price']/text()").getall(),
'date': response.url.split('/')[-3],
'track': response.url.split('/')[-4],
'rug': row.xpath('.//td[@class="table__cell--tight race-runners__box"]/sprite-svg/@name').get()
}
.get()(返回单个字符串或 None)替代 .extract()(已弃用,返回列表),符合 Scrapy 2.0+ 最佳实践;.get(default='') 显式指定默认值,避免后续处理报错;response.css() 或 response.xpath() 提取同一页面级字段——不仅低效,还易因 DOM 结构误判导致逻辑错误;










