XPath在控制台有效但Scrapy中无结果,MLB数据爬取失败求助
问题原因及解决方法
核心问题分析
- XPath语法错误:原路径
//table[@class="wikitablet"/body/tr]存在两处错误:- 表格的class属性实际是
wikitable,不是wikitablet; - HTML中表格的行容器是
tbody而非body,且路径分隔符使用错误(table和tbody之间应该用/,而非/body)。
- 表格的class属性实际是
- 节点层级混淆:循环遍历的
row已经是tr节点,内部XPath却额外嵌套了tr(如.//tr/th[2]),导致无法定位到正确的单元格;同时数据行的单元格标签是td,而非表头用的th,混淆了两类标签。 - 代码缩进错误:
parse方法没有缩进在BasketSpider类内部,导致Scrapy无法识别这个爬虫的解析方法。
解决步骤
- 修正XPath路径:
定位表格行的正确XPath应为//table[@class="wikitable"]/tbody/tr,先匹配class为wikitable的表格,再遍历其下tbody中的所有行。 - 区分表头与数据行:
- 表头行的单元格用
th,数据行的单元格用td;遍历行时可以跳过表头,或者分别处理。 - 行内XPath直接基于当前
tr节点定位单元格,无需额外嵌套tr。
- 表头行的单元格用
- 修复代码缩进:将
parse方法缩进至BasketSpider类内部,确保Scrapy能调用该方法。
修正后的代码
import scrapy class BasketSpider(scrapy.Spider): name = "basket" allowed_domains = ["wiki.stat.ucla.edu"] start_urls = ["http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_MLB_HeightsWeights"] def parse(self, response): # 跳过表头行,从第二行开始遍历数据 for row in response.xpath('//table[@class="wikitable"]/tbody/tr[position()>1]'): yield { 'name': row.xpath('.//td[1]/text()').get().strip(), 'team': row.xpath('.//td[2]/text()').get().strip(), 'position': row.xpath('.//td[3]/text()').get().strip(), 'height': row.xpath('.//td[4]/text()').get().strip(), 'weight': row.xpath('.//td[5]/text()').get().strip(), }
避坑提示
- 验证XPath时,直接在Scrapy Shell中使用
response.xpath("路径").getall()测试,不要仅依赖浏览器控制台(浏览器会自动补全HTML节点,如tbody,而Scrapy获取的是原始HTML)。 - 仔细检查HTML结构:查看页面原始源码(F12查看“页面源代码”而非元素面板),确认标签和属性的真实值。
- 严格遵循Python缩进规则,类的方法必须缩进在类定义内部。
内容的提问来源于stack exchange,提问作者mohamed agnaby
相关产品推荐
相关产品推荐

