19

我正在尝试使用 html5lib 将 html 页面解析为可以使用 xpath 查询的内容。html5lib 的文档几乎为零,我花了太多时间试图解决这个问题。最终目标是拉出表格的第二行:

<html>
    <table>
        <tr><td>Header</td></tr>
        <tr><td>Want This</td></tr>
    </table>
</html>

所以让我们试试吧:

>>> doc = html5lib.parse('<html><table><tr><td>Header</td></tr><tr><td>Want This</td> </tr></table></html>', treebuilder='lxml')
>>> doc
<lxml.etree._ElementTree object at 0x1a1c290>

看起来不错,让我们看看我们还有什么:

>>> root = doc.getroot()
>>> print(lxml.etree.tostring(root))
<html:html xmlns:html="http://www.w3.org/1999/xhtml"><html:head/><html:body><html:table><html:tbody><html:tr><html:td>Header</html:td></html:tr><html:tr><html:td>Want This</html:td></html:tr></html:tbody></html:table></html:body></html:html>

大声笑吗?

严重地。我打算使用一些 xpath 来获取我想要的数据,但这似乎不起作用。那么我能做什么呢?我愿意尝试不同的库和方法。

4

7 回答 7

24

缺少文档是避免使用库 IMO 的一个很好的理由,无论它多么酷。您是否热衷于使用 html5lib?你看过lxml.html吗?

这是使用 lxml 执行此操作的一种方法:

from lxml import html
tree = html.fromstring(text)
[td.text for td in tree.xpath("//td")]

结果:

['Header', 'Want This']
于 2010-04-01T05:13:30.257 回答
19

您要使用的是namespaceHTMLElements参数,由于某种原因默认为 True。

doc = html5lib.parse('''<html>
    <table>
        <tr><td>Header</td></tr>
        <tr><td>Want This</td></tr>
    </table>
</html>
''', treebuilder='lxml', namespaceHTMLElements=False)

print lxml.html.tostring(doc)

但是,使用 lxml.html 可能更容易。

于 2011-02-22T02:03:29.147 回答
4

我总是建议尝试lxml图书馆。它速度极快,并且具有许多功能。

如果您需要,它还支持 html5lib 解析器:html5parser

>>> from lxml.html import fromstring, tostring

>>> html = """
... <html>
...     <table>
...         <tr><td>Header</td></tr>
...         <tr><td>Want This</td></tr>
...     </table>
... </html>
... """
>>> doc = fromstring(html)
>>> tr = doc.cssselect('table tr')[1]
>>> print tostring(tr)
<tr><td>Want This</td></tr>
于 2010-04-01T05:17:53.713 回答
1

我相信你可以对 lxml 对象进行 css 搜索.. 像这样

elements = root.cssselect('div.content')
data = elements[0].text
于 2010-04-01T04:33:36.297 回答
1

使用BeautifulSoup,您可以使用

>>> soup = BeautifulSoup.BeautifulSoup('<html><table><tr><td>Header</td></tr><tr><td>Want This</td></tr></table></html>')
>>> soup.findAll('td')[1].string
u'Want This'
>>> soup.findAll('tr')[1].td.string
u'Want This'

(显然这是一个非常粗略的例子,但是是的。)

于 2010-04-01T04:36:17.963 回答
1

由于 html5lib(默认情况下)创建包含(正确)名称空间信息的树,因此您在查询中也指定了(正确的)名称空间。

XPath 查询示例:

import html5lib
inp='''<html>
    <table>
        <tr><td>Header</td></tr>
        <tr><td>Want This</td></tr>
    </table>
</html>'''
xns = '{http://www.w3.org/1999/xhtml}'
d = html5lib.parse(inp)
s = d.findall('.//{}td'.format(xns))[-1].text
print(s)

输出:

想要这个

没有 XPath 的结果相同:

s = d.find(xns+'body').find(xns+'table').find(xns+'tbody') \
     .findall(xns+'tr')[-1].find(xns+'td').text

或者,您也可以告诉 html5lib 在解析期间避免添加任何命名空间信息:

d = html5lib.parse(inp, namespaceHTMLElements=False)
s = d.findall('.//td')[-1].text
print(s)

输出:

想要这个
于 2017-04-19T17:08:16.070 回答
-5

尝试使用 jquery。您可以检索所有元素。或者,您可以在行上放一个 id 并将其拉出。

1) ... ...

$("td")[1].innerHTML 将是您想要的

2) ... ...

$("#blah").text() 将是你想要的

于 2010-04-01T04:30:37.680 回答