使用lxml.html XPath爬取时第二行销售日期与价格返回空列表求助
解决lxml XPath爬取第二行数据返回空值的问题
看起来你遇到的问题根源在于绝对XPath的脆弱性——你依赖的严格层级路径很容易和实际DOM结构不匹配,导致找不到第二行的元素。咱们一步步来解决这个问题:
问题分析
你用的绝对XPath(比如/html/body/table[2]/.../tr[4])完全依赖页面DOM的固定层级,但实际页面中可能存在你没注意到的结构差异:比如表格里可能有隐藏的<tr>、额外的表头行,或者你复制的HTML片段不完整(比如第二行的<td>没有被<tr>包裹,这显然不符合HTML规范,实际页面里应该是每个数据行都在<tr>中)。
另外,你处理字符串的方式可以简化,不用正则拆分,直接用XPath的normalize-space()或者Python的strip()就能清理多余空格和 。
解决方案:改用基于特征的相对XPath
与其用容易断裂的绝对路径,不如根据元素的共同特征来定位,比如所有销售日期和价格都在class="BodyCopyBold9"的<span>里,且位于数据行的第1和第3个<td>中。
修改后的代码如下:
import lxml.html import requests data = requests.get("https://bcpa.net/RecInfo.asp?URL_Folio=504201170140").content htmlelement = lxml.html.fromstring(data) # 先定位所有包含销售数据的行(匹配有BodyCopyBold9 span的tr) sales_rows = htmlelement.xpath("//table[9]//tr[td/span[@class='BodyCopyBold9']]") # 遍历每一行提取数据 for idx, row in enumerate(sales_rows, 1): # 使用normalize-space直接在XPath中清理空格和换行 saledate = row.xpath("normalize-space(.//td[1]/span/text())") saleprice = row.xpath("normalize-space(.//td[3]/span/text())") print(f"Sale Date {idx}: {saledate}") print(f"Sale Price {idx}: {saleprice}")
为什么这个方法有效?
- 相对路径更稳定:
.//td[1]/span是相对于当前行<tr>的路径,不管外层表格层级怎么变,只要数据行的结构不变就能拿到数据。 - 特征匹配更准确:
//table[9]//tr[td/span[@class='BodyCopyBold9']]精准定位到包含销售数据的行,过滤掉无关的表头或空行。 - XPath内置函数简化处理:
normalize-space()会自动去除字符串首尾的空格、换行和 ,省去了正则拆分的麻烦。
关于你原代码的问题排查
如果一定要用绝对路径,你可以用htmlelement.xpath("//table[9]//tr")打印出所有的<tr>数量,看看tr[4]是否真的是你要的第二行数据——很可能你的路径里的tr索引不对,比如中间有一个隐藏的行导致索引偏移。
内容的提问来源于stack exchange,提问作者Mitch Espi
相关产品推荐
相关产品推荐

