xpath 路径中出现 `/html[2]` 并非表示页面存在多个 `` 根元素,而是解析器(如 lxml 或某些浏览器扩展)在处理不规范 html 时生成的伪文档结构;标准 html 规范严格禁止嵌套或并列的 `` 标签。
在实际网页开发与自动化解析中,你可能会观察到同一页面在 Chrome 开发者工具中复制的 XPath 是 /html/body/...,而用 requests.get() 获取响应后经 lxml.html.fromstring() 解析得到的 XPath 却是 /html[2]/article/...。这种差异并非源于 HTML 页面本身包含多个 元素——这是根本违反 HTML 规范的。
根据 MDN Web Docs, 是文档的根元素,具有两个关键约束:
因此,如下写法均非法:
那么 /html[2] 是从何而来?根本原因在于 HTML 解析器对破损或非标准 HTML 的容错处理机制。例如:
... ... ...
此时 /html[2] 表示该 DOM 树中的第二个 节点——但它不是原始 HTML 的合法部分,而是解析器生成的“修复产物”。
✅ 正确做法是:
from lxml import html
tree = html.fromstring(response.content)
# ✅ 推荐:忽略 html 层级,直接查 body 下结构
element = tree.xpath('//article/section/div[6]/text()')
# ✅ 或使用相对路径 + 显式命名空间
element = tree.xpath('/html/body/article/section/div[6]/text()')⚠️ 注意事项:

总结:/html[2] 是解析器对脏数据的妥协结果,而非 HTML 合法特性。编写健壮的爬虫 XPath,应优先采用语义化、相对路径和属性过滤,而非依赖绝对路径中的 html[n] 索引。