You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy使用xpath提取网页节点源码返回结果异常如何解决

问题原因

这个现象是Scrapy底层依赖的lxml解析库版本过低导致的已知序列化bug,和你写的XPath规则、调用的extract/get类方法没有关系。
lxml 4.3.0之前的版本存在明确缺陷:当解析包含换行、空白缩进的表格类节点时,对选中节点执行源码序列化操作(Scrapy的extract()、get()、getall()、extract_first()底层都依赖这个操作)会错误地从当前节点的起始标签开始,一直输出到整个HTML文档的末尾,和你遇到的输出完全一致。
你可以自行验证节点定位本身是正确的:执行len(selector.xpath("//td"))会返回4,和预期的td节点数量一致;//td/text()能正确提取每个td内的文本,也证明节点选择逻辑没有问题,故障仅出在节点源码转字符串输出的环节。
另外如果创建Selector时手动指定了type="xml",也可能触发同类解析异常,解析普通HTML内容用默认的HTML解析模式即可,不要强制使用XML解析模式。

解决方案

永久修复

直接升级lxml到4.3.0及以上版本即可解决bug,执行命令:

pip install --upgrade lxml

如果升级后存在依赖兼容问题,可以同步升级Scrapy到最新稳定版:

pip install --upgrade Scrapy

临时规避方案

如果暂时无法升级运行环境的依赖,可以通过字符串截取的方式手动截断多余内容,拿到独立的td标签源码,示例代码如下:

from scrapy import Selector
html = '''
<html><head></head><body><table>

<tr> <td>a1</td> <td>b1</td> </tr>
<tr> <td>a2</td> <td>b2</td> </tr>

</table></body></html>
'''

def get_clean_node(node, tag):
    raw_content = node.get()
    close_tag = f'</{tag}>'
    return raw_content[:raw_content.index(close_tag) + len(close_tag)]

selector = Selector(text=html)
temp = [get_clean_node(td, 'td') for td in selector.xpath("//td")]
print(temp)

运行后即可得到预期的输出:

['<td>a1</td>', '<td>b1</td>', '<td>a2</td>', '<td>b2</td>']

内容的提问来源于stack exchange,提问作者watfe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 07:48:27