我正在尝试使用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>
LOL WUT?
严重。我打算使用一些xpath来获取我想要的数据,但这似乎不起作用。那我该怎么办?我愿意尝试不同的图书馆和方法。
答案 0 :(得分:20)
缺少文档是避免图书馆IMO的一个很好的理由,无论它有多酷。你是否坚持使用html5lib?你看过lxml.html吗?
以下是使用lxml执行此操作的方法:
from lxml import html
tree = html.fromstring(text)
[td.text for td in tree.xpath("//td")]
结果:
['Header', 'Want This']
答案 1 :(得分:17)
您要使用的是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可能更容易。
答案 2 :(得分:3)
我总是建议试用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>
答案 3 :(得分:2)
使用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'
(显然这是一个非常粗糙的例子,但是你。)
答案 4 :(得分:1)
我相信你可以在lxml对象上进行css搜索..就像这样
elements = root.cssselect('div.content')
data = elements[0].text
答案 5 :(得分:0)
由于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)
输出:
Want This
没有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)
输出:
Want This
答案 6 :(得分:-4)
尝试使用jquery。你可以检索所有元素。或者,您可以在行上放置一个ID并将其拉出来。
1)......
$(“td”)[1] .innerHTML将是你想要的
2)......
$(“#blah”)。text()将是你想要的