我正在使用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???????????>]
为<table>
代码的孩子遗漏了<p>
标记的任何想法?
如何选择此<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。
我真的不知道如何更简洁。建设性意见(一如既往)受到赞赏。
答案 0 :(得分:1)
我认为问题在于lxml试图通过HTML规则来玩。根据这些规则,<table>
(块级元素)不能是<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>
的子项:
<html>
<body><p>
</p><table>
<tr>
<td>XXX</td>
</tr>
</table>
</body></html>
<a>
是一个内联元素,因此它包含在getchildren()
的返回值中是有意义的。您必须找到其他方法来识别您感兴趣的<table>
元素。
http://ohhla.com/YFA_natedogg.html文档声称是XHTML,但它有很多错误,无法解析为XML文档。