【问题标题】:Getting non-contiguous text with lxml / ElementTree使用 lxml / ElementTree 获取非连续文本
【发布时间】:2011-04-10 16:26:33
【问题描述】:

假设我有这种 HTML,我需要使用 lxml / ElementTree 从中选择“text2”:

<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>

如果我已经将 div 元素作为 mydiv,则 mydiv.text 仅返回“text1”。

使用 itertext() 似乎有问题或最麻烦,因为它会遍历 div 下的整个树。

是否有任何简单/优雅的方法可以从元素中提取非第一个文本块?

【问题讨论】:

  • 这似乎是一个错误。你试过用findtext(path)吗?
  • 由于我的回答显然没有回答您的问题,您能否进一步解释一下您在寻找什么?

标签: python html-parsing lxml elementtree


【解决方案1】:

此类文本将位于元素子元素的tail 属性中。如果您的元素在 elem 中,那么:

elem[0].tail

会给你元素中第一个子元素的尾部文本,在你的情况下是你正在寻找的"text2"

【讨论】:

    【解决方案2】:

    正如 llasram 所说,任何不在text 属性中的文本都将在子节点的tail 属性中。

    例如,这是提取节点中所有文本块(第一个和其他)的最简单方法:

    html = '<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>'
    
    import lxml.html    # ...or lxml.etree as appropriate
    div = lxml.html.fromstring(html)
    
    texts = [div.text] + [child.tail for child in div]
    # Result: texts == ['text1', 'text2', 'text3']
    # ...and you are guaranteed that div[x].tail == texts[x+1]
    # (which can be useful if you need to access or modify the DOM)
    

    如果您宁愿牺牲该关系以防止 texts 可能包含空字符串,您可以改用它:

    texts = [div.text] + [child.tail for child in div if child.tail]
    

    我没有用普通的旧 stdlib ElementTree 测试过这个,但它也应该适用。 (当我看到 Shane Holloway 的 lxml 特定解决方案时,我才想到这一点)我只是更喜欢 LXML,因为它对 HTML 的意识形态有更好的支持,而且我通常已经为 lxml.html.clean 安装了它。

    【讨论】:

      【解决方案3】:

      嗯,lxml.etree 提供了完整的 XPath 支持,它允许您处理文本项:

      >>> import lxml.etree
      >>> fragment = '<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>'
      >>> div = lxml.etree.fromstring(fragment)
      >>> div.xpath('./text()')
      ['text1', 'text2', 'text3']
      

      【讨论】:

      • doc.xpath('/div/text()')[1:2] 将为您提供来自元素的非第一个文本
      • 好吧,“一种提取非第一个文本块的方法”包括在将所有文本项作为列表获取之后的许多可能性,例如random.choice(div.xpath('./text()')[1:])set(div.xpath('./text()')[1:]).pop()。但是,由于 OP 知道足以询问 lxml,我认为列表操作是小豆子。
      【解决方案4】:

      使用node.text_content() 将节点下的所有文本作为单个字符串获取。

      【讨论】:

        猜你喜欢
        • 2013-03-15
        • 1970-01-01
        • 2015-01-05
        • 2013-03-14
        • 2010-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多