【问题标题】:How do I parse with LXML recursively in an elegant way?如何以优雅的方式递归解析 LXML?
【发布时间】:2015-10-29 02:26:01
【问题描述】:

例如,考虑以下 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()&lt;div id="element1"&gt; 中搜索?

编辑-

在 lxml 中发现了奇怪的方法:

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

【问题讨论】:

  • 预期输出是什么? text1text2text3 ?
  • @falsetru 是的。我正在尝试解析这些文本。

标签: python web-scraping lxml


【解决方案1】:

您的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() 来去除它们。

【讨论】:

  • 谢谢。如果我想像“在从//div[starts-with(@id, 'element')] 返回的每个元素下搜索”一样递归地进行 xpath 搜索怎么办?
  • // 是在元素下的任意一级搜索,/ 是在上一个元素的下一级搜索,可以使用-//div[starts-with(@id, 'element')]//&lt;what you want&gt;//div[starts-with(@id, 'element')]/&lt;what you want at 1 level&gt;
  • 你应该使用一些xpath的在线教程,它很容易学习/理解
【解决方案2】:

您可以使用starts-with 获取div,其中idelement 开头

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

这会产生

text1
text2
text3

【讨论】:

    【解决方案3】:

    如果你想获取一个元素的所有子元素,我建议使用iter()

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

    输出:

    text1
    text2
    text3
    

    你也可以定义一个标记名tree.iter(tag="div")

    【讨论】:

      猜你喜欢
      • 2020-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多