如何以优雅的方式递归解析 LXML?

How do I parse with LXML recursively in an elegant way?

例如,考虑以下 HTML:

<div class="class1">
  <div id="element1">
    text1
  </div>
  <div id="element2">
    text2
  </div>
  <div id="element3">
    text3
  </div>
</div>   

我想要实现的是解析不同的元素,哪些属性是已知的。

我现在的做法:

index = len(tree.xpath('//div[@class="class1"]')
for i in range(0, index):
    print tree.xpath('//div[@class="class1"][i]/text()')

但是当涉及到较长的 xpath 时,它会变得有点混乱。 还有其他方法吗?

编辑-

例如,

first_elem = tree.xpath('//div[@class="class1"]')[0]

是否可以这样做:

first_elem.xpath()<div id="element1"> 中搜索?

编辑-

在 lxml 中找到了执行此操作的奇怪方法:

for i in tree.xpath('//div[@class="class1"]'):
    str1 = html.tostring(i)
    tree = html.fromstring(str1)
    < do things here >

您可以使用 starts-with 得到 div 其中 idelement

开头
for i in tree.xpath("//div[starts-with(@id, 'element')]/text()"):
    print(i.strip())

这会产生

text1
text2
text3

您的 xpath 似乎是错误的,当您这样做时 -

tree.xpath('//div[@class="class1"][i]/text()')

i 不会在内部自动被替换。在任何情况下,你都不需要做你正在做的事情,tree.xpath 会 return 所有匹配元素的列表,你可以简单地使用你想要的 xpath(即使它会产生多个元素) ,然后遍历结果并打印出来。示例(或您正在尝试做的事情)-

for i in tree.xpath('//div[@class="class1"]/div/text()'):
    print i

这应该打印主 div 中每个 div 内的文本,属性 classclass1


你甚至不需要它,如果你知道一种唯一标识元素的方法(使用 attributes/indexing 等),你可以直接使用它,例如,获取 [=19= 的文本] , 使用 -

for i in tree.xpath('//div[@id="element1"]/text()'):
    print i

此外,您的 xml 似乎有很多不需要的换行符和空格,您可以通过调用 i.strip() 去除它们。

如果你想得到一个元素的所有子元素,我推荐使用iter():

for element in tree.iter():
    print element.text.strip()

输出:

text1
text2
text3

您还可以定义标记名tree.iter(tag="div")