使用lxml从html中提取属性
问题描述:
我使用lxml
从html页面检索标签的属性。 HTML页面的格式如下:使用lxml从html中提取属性
<div class="my_div">
<a href="/foobar">
<img src="my_img.png">
</a>
</div>
我用检索<a>
标签内的网址和同一<div>
内<img>
标签的src
值时,Python脚本是这样的:
from lxml import html
...
tree = html.fromstring(page.text)
for element in tree.xpath('//div[contains(@class, "my_div")]//a'):
href = element.xpath('/@href')
src = element.xpath('//img/@src')
为什么我不能得到字符串?
答
如果你改变你的代码:
from lxml import html
...
tree = html.fromstring(page.text)
for element in tree.xpath('//div[contains(@class, "my_div")]//a'):
href = element.items()[0][1] #gives you the value corresponding to the key "href"
src = element.xpath('//img/@src')[0]
print(href, src)
你会得到你所需要的。
documentation of lxml
提到了其中的一些内容,但我觉得它缺少一些东西,您可能要考虑使用交互式python shell来研究由tree.xpath()
返回的实例的属性。或者你可以完全查看另一个解析器,如BeautifulSoup,它有很好的例子和文档。只是分享...
答
你没有得到你想要的结果的原因是你试图从下一个孩子而不是现有的节点获取属性。
看到这个:
from lxml import html
s = '''<div class="my_div">
<a href="/foobar">
<img src="my_img.png">
</a>
</div>'''
tree = html.fromstring(s)
# when you do path... //a, you are ALREADY at 'a' node
for el in tree.xpath('//div[contains(@class, "my_div")]//a'):
# you were trying to get next children /@href, which doesn't exist
print el.xpath('@href') # you should instead access the existing node's
print el.xpath('img/@src') # same here, not /img/@src ...
['/foobar']
['my_img.png']
希望这有助于。
答
您正在使用lxml,因此您正在使用lxml对象 - HtmlElement实例进行操作。 的HtmlElement从etree.Element嵌套:http://lxml.de/api/lxml.etree._Element-class.html, 它有得到方法,返回attrubute值。 所以对于你的正确方法是:
from lxml import html
...
tree = html.fromstring(page.text)
for link_element in tree.xpath('//div[contains(@class, "my_div")]//a'):
href = link_element.get('href')
image_element = href.find('img')
if image_element:
img_src = image_element.get('src')
我同意不同意和** ** LXML可能不是最适合的XPath处理,但高于一切,这是一个非常容易使用,快速和强大的HTML/xml解析器。 ** BeautifulSoup **本身没有解析器,它使用Python标准库(它比** lxml **相对要慢),但可以配置为使用第三方,如** lxml **,甚至他们的doc建议安装** lxml **以提高速度。但我确实同意** BeautifulSoup **有很好的文档记录和易于学习。 – Anzel 2014-11-22 04:00:49
@Anzel,我同意你说的一切。的确,BeautifulSoup提到lxml是一个快速库,不应该被忽视。只是文档通常是示例的最佳来源,对于社区采用图书馆起着重要作用。注意事项:BeautifulSoup标记问题的数量与标记为lxml(〜2/1)的问题的数量。 – 2014-11-22 09:01:35