使用XPath和变量进行lxml.html解析

2024-05-23 14:13:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这个HTML片段

<div id="dw__toc">
<h3 class="toggle">Table of Contents</h3>
<div>

<ul class="toc">
<li class="level1"><div class="li"><a href="#section">#</a></div>
<ul class="toc">
<li class="level2"><div class="li"><a href="#link1">One</a></div></li>
<li class="level2"><div class="li"><a href="#link2">Two</a></div></li>
<li class="level2"><div class="li"><a href="#link3">Three</a></div></li>

现在我想用lxml.html解析它。最后,我想要一个函数,在这里我可以提供一个searchterm(即“one”),函数应该返回

One
#link1

现在我试图在XPath中获取一个变量。

有效:

import lxml.html
html = lxml.html.parse("www.myurl.com/slash/something")

test=html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a/text()='One'")

print test

尝试变量。我想用一个变量替换硬编码的'One',我可以稍后返回函数。

不起作用:

import lxml.html
html = lxml.html.parse("www.myurl.com/slash/something")

desiredvars = ['One']
myresultset=((var, html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a[text()='%s']"%(var))[0]) for var in desiredvars)

for each in myresultset: 
        print each

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
IndexError: list index out of range

这是基于这个答案:https://stackoverflow.com/a/10688235/2320453 知道为什么不行吗?这是做这种事的“正确方法”吗?

编辑: 总结一下: 我想在a-Tags中搜索并从这个属性中获取文本,但是我不想有一个完整的列表,而是希望能够使用一个变量进行搜索。 伪代码:

import lxml.html
html = lxml.html.parse("www.myurl.com/slash/something")

searchterm = 'one'

test=html.xpath("...a/text()=searchterm")

print test

预期结果

One
#link1

Tags: 函数intestdivcomhtmlliul
2条回答

你的第一个例子很好,但可能不是你想的那样:

test=html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a/text()='One'")

这返回的是一个布尔值,如果xpath表达式左侧的结果集中的任何节点的条件...='One'为true,则返回值为true。这就是为什么在第二个示例中会出现错误:True[0]无效。

您可能希望所有节点都与expession匹配,将'One'作为文本。相应的表达式为:

test=html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a[text()='One']")

这将返回一个nodeset作为结果,或者如果您只需要url作为字符串:

test=html.xpath("//ul[@class='toc']/li[@class='level2']/div[@class='li']/a[text()='One']/@href")
# returns: ['#link1']

我试过玛塔的回答,但对我来说没用:

div_name = 'foo'
my_div = x.xpath(".//div[@id=%s]" %div_name)[0]

我在他们的网站上找到了这个http://lxml.de/xpathxslt.html#the-xpath-method给那些可能有同样问题的人:

div_name = 'foo'
my_div = x.xpath(".//div[@id=$name]", name=div_name)[0]

相关问题 更多 >