我有一个结构如下的HTML文档:
<html>
<li>
<a href="" />a1</a>
<other tags ... />
<li>
<a href="">a2</a>
<another one tag ... />
<a name=3>
</li>
</li>
<li>
...
</li>
我需要找到位于 li 元素下的所有父元素,并为 name=3 的元素构建路径。在此示例中,它应该是 a1/a2。我使用 lxml 并编写了以下 Python 代码:
import lxml
...
def get_path_for_series(self, html, series):
current = html.xpath('//a[@name="%s"]' % series)[0]
path = list()
while True:
category = current.xpath('.//ancestor::li[1]//a[1]')
if len(category) == 0:
break
path.append(self.clear(category[0].text_content()))
current = category[0]
return '/'.join(path)
它正确地找到了第一个元素,但随后我有一个无限循环。我做错了什么?
您的 while 循环首先遍历到祖先 li
并获取后代a[1]
。然后从当前a
,在下一个循环中,您的 XPath 将再次遍历到同一个li
祖先并返回相同的a
元素,这将永远持续下去(添加print current
进行验证。我在同一内存位置看到了Element
,这意味着它们是同一个实例,一遍又一遍地打印)。
您可以尝试从目标a[@name="%s"]
向上移动树状态,并反向连接收集的路径步骤,如下所示:
def get_path_for_series(self, html, series):
current = html.xpath('//a[@name="%s"]' % series)[0]
path = list()
parent = current.xpath('parent::li')
while parent:
a = parent[0].xpath('a[1]')[0]
path.append(a.text)
parent = parent[0].xpath('parent::li')
# join `path` in reversed order
return '/'.join(path[::-1])