我正在使用 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 仅检测初始 anchor 标记 <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???????????>]
关于为什么 <table>
的任何想法<p>
中缺少标签标签的 child ?
我怎样才能选择这个 <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 .
我真的不知道如何比这更简洁。建设性意见表示赞赏(一如既往)。
- 链接到我已经阅读过的页面(例如 How to create a Minimal, Complete, and Verifiable example)没有评论 不是建设性的批评。
- 指出我可能错过了哪些步骤,或者将来(从特定资源)需要改进的地方是建设性的批评,对我自己和整个社区都有好处。
- 我很乐意接受有关如何改进我的帖子的建议,但请提供实际的建议。请记住,多个人可能会阅读相同的资源并得出不同的结论。
最佳答案
我认为问题在于 lxml 试图按照 HTML 规则进行游戏。根据这些规则,<table>
( block 级元素)不能是 <p>
的子元素.参见 https://www.w3.org/TR/html4/struct/text.html#h-9.3.1 .
简短演示:
from lxml import html
test = """
<html>
<p>
<table>
<tr>
<td>XXX</td>
</tr>
</table>
</p>
</html>"""
root = html.fromstring(test)
# Just print the string representation of the parsed HTML
print(html.tostring(root).decode("UTF-8"))
在此代码的输出中,我们可以看到 lxml 拒绝解释 <table>
作为 <p>
的 child :
<html>
<body><p>
</p><table>
<tr>
<td>XXX</td>
</tr>
</table>
</body></html>
<a>
是一个内联元素,所以它包含在 getchildren()
的返回值中是有意义的.您将不得不找到其他方法来识别 <table>
您感兴趣的元素。
http://ohhla.com/YFA_natedogg.html document自称是XHTML,但错误较多,无法解析为XML文档。
关于python - 使用 lxml 解析段落标记的子项时缺少子项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44976672/