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

时间:2015-08-06 05:11:50

标签: python web-scraping lxml

例如,请考虑以下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 >

3 个答案:

答案 0 :(得分:1)

您可以使用starts-with获取divid开头的element

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

,这会产生

text1
text2
text3

答案 1 :(得分:1)

如果您想获取元素的所有Childs,我建议使用iter()

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

输出:

text1
text2
text3

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

答案 2 :(得分:0)

当您这样做时,xpath似乎错了 -

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

i不会自动替换。在任何情况下,你不需要做你正在做的事情,tree.xpath将返回所有匹配元素的列表,你可以简单地使用你想要的xpath(即使它导致多个元素),然后迭代结果并打印出来。示例(或您要做的事) -

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

这应该将主要div中每个div内的文字打印为属性classclass1

如果您知道一种唯一标识元素的方法(使用属性/索引等),您甚至不需要它,您可以直接使用它来获取element1的文本,使用 -

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

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