【发布时间】:2017-12-12 02:23:55
【问题描述】:
我正在使用 Python 库 lxml 对从 this url 检索到的 HTML 执行 XML 解析。过去我在使用 lxml 时没有遇到任何问题,但是我可能刚刚遇到了一个错误,即缺少子元素(在 lxml 树中)的形式,它明显地出现在 HTML 中。
这是我用来解析 HTML 的 Python 代码:
from urllib.request import urlopen
from lxml import etree
html_response = urlopen("http://ohhla.com/YFA_natedogg.html")
html_parser = etree.HTMLParser()
tree = etree.parse(html_response, html_parser)
tree.xpath("//table[@id='AutoNumber7']/tr[2]/td/p[1]")[0]
我正在解析的网站的 HTML 代码的简化版本如下所示:
<table id='AutoNumber7'>
<tbody>
<tr></tr>
<tr>
<td>
# ... (irrelevant tags) ...
<p>
<a></a>
# The following <table> tag is what I need to target:
<table></table>
</p>
# ... (seven <p> tags identical to the above) ...
</td>
</tr>
</tbody>
当我在控制台中运行tree.xpath("//table[@id='AutoNumber7']/tr[2]/td/p[1]")[0].getchildren()
时,lxml 只检测到初始锚标记<a> 并忽略我需要选择的兄弟<table> 标记(由代码中的上述注释表示)。
这是控制台输出:
tree.xpath("//table[@id='AutoNumber7']/tr[2]/td/p[1]")[0].getchildren()
Out[22]: [<Element a at 0x2904a2a5808>]
我希望看到的是:
tree.xpath("//table[@id='AutoNumber7']/tr[2]/td/p[1]")[0].getchildren()
Out[22]: [<Element a at 0x2904a2a5808>, <Element table at 0x???????????>]
知道为什么<p> 标签的子标签中缺少<table> 标签吗?
如何选择这个<table> 标签?我需要解析 table 标记中的所有内容,但 lxml 似乎无法将其识别为有效的子元素。如果有人可以为所需的<table> 标签提供有效的 xpath 选择器,我将非常感激!
注意:我知道我应该看到[<Element tr at 0x??????????>, <Element tr at 0x???????????>, ...] 而不是[<Element table at 0x??????????>],但我试图更简洁。
编辑:对于那些不认为上述代码可重现的人,只需将其复制并粘贴到控制台中即可:
from urllib.request import urlopen
from lxml import etree
html_response = urlopen("http://ohhla.com/YFA_natedogg.html")
html_parser = etree.HTMLParser()
tree = etree.parse(html_response, html_parser)
print(tree.xpath("//table[@id='AutoNumber7']/tr[2]/td/p[1]")[0].getchildren())
与之前我尝试解析的 HTML 一样位于 here。
我真的不知道如何比这更简洁。建设性的 cmets 受到赞赏(一如既往)。
- 链接到我已经阅读过的页面(例如How to create a Minimal, Complete, and Verifiable example)没有评论 不是建设性的批评。
- 指出我可能遗漏了哪些步骤,或者将来需要改进的地方(来自特定资源)是建设性的批评,对我自己和整个社区都有好处。
- 我很乐意接受有关如何改进我的帖子的建议,但请提供实际的建议。请记住,几个人可能会阅读相同的资源并得出不同的结论。
【问题讨论】:
-
"这是我用来解析 HTML 的 Python 代码" - 不,我认为这不是您正在使用的 Python 代码。特别是
tree从未定义过。请复制粘贴,切勿重新键入您正在使用的确切短程序。请参阅minimal reproducible example 了解更多信息。 -
@Rob 感谢您指出这一点,代码没有重新输入。我只是错过了复制那行代码。代码分散在一个大方法中,所以我只需要复制会重现上述问题的相关行。
-
XPath 中的
tbody在哪里?既然它不见了,为什么你会在控制台中看到你声称的a元素? -
@kjhughes 出于某种原因(我不知道),当包含
<tbody>时,xpath 选择器不起作用。如果您按原样运行代码:tree.xpath("//table[@id='AutoNumber7']/tr[2]/td/p[1]")[0].getchildren(),您应该会看到与我收到的相同的控制台输出。 -
实际的 HTML 与您发布的不同,没有
tbody。回去创建一个真正的 minimal reproducible example,不要再浪费大家的时间了。你的问题应该独立存在——不依赖于任何外部链接——这样它对未来的读者就会有价值。问题也应该是可验证,仅基于您的问题。
标签: python html xpath xml-parsing lxml