【问题标题】:How do I get the full XML or HTML content of an element using ElementTree?如何使用 ElementTree 获取元素的完整 XML 或 HTML 内容?
【发布时间】:2010-09-27 16:38:03
【问题描述】:

也就是说,所有的文本和子标签,没有元素本身的标签?

拥有

<p>blah <b>bleh</b> blih</p>

我想要

blah <b>bleh</b> blih

element.text 返回 "blah" 并且 etree.tostring(element) 返回:

<p>blah <b>bleh</b> blih</p>

【问题讨论】:

    标签: python xml api elementtree


    【解决方案1】:

    ElementTree 完美运行,您必须自己组装答案。像这样的...

    "".join( [ "" if t.text is None else t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )
    

    感谢 JV amd PEZ 指出错误。


    编辑。

    >>> import xml.etree.ElementTree as xml
    >>> s= '<p>blah <b>bleh</b> blih</p>\n'
    >>> t=xml.fromstring(s)
    >>> "".join( [ t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )
    'blah <b>bleh</b> blih'
    >>> 
    

    不需要尾巴。

    【讨论】:

    • 只是指出一个错字-方法名称-“finall”,我认为应该是“findall”。即使使用了 findall,它也会产生这个pastebin.com/f6de9a841。请修改您的答案。
    • 我正在做与此类似的事情,但带有 for 外观。你实际上错过了尾巴。
    • 尾部是结构结束标记后的多余空格。
    【解决方案2】:

    这是我最终使用的解决方案:

    def element_to_string(element):
        s = element.text or ""
        for sub_element in element:
            s += etree.tostring(sub_element)
        s += element.tail
        return s
    

    【讨论】:

    • 如果没有文本或没有尾巴,那会失败,不是吗?
    • PEZ,是的,当没有文本时它会失败,只是通过运行我的代码找到它并修复它。我有很多没有尾巴的例子,而且没有失败。不知道为什么。
    • 只是一个吹毛求疵:字符串上的 += 性能较差。最好累积一个字符串列表,并在末尾添加 ''.join。
    • 您可能需要递归并再次在子元素上调用element_to_string 以捕获所有文本,即for sub_element in element: s += element_to_string(sub_element)
    【解决方案3】:

    这些都是很好的答案,可以回答 OP 的问题,特别是如果问题仅限于 HTML。但是文档天生就是杂乱无章的,元素嵌套的深度通常是无法预测的。

    要模拟 DOM 的 getTextContent(),您必须使用(非常)简单的递归机制。

    仅获取纯文本:

    def get_deep_text( element ):
        text = element.text or ''
        for subelement in element:
            text += get_deep_text( subelement )
        text += element.tail or ''
        return text
    print( get_deep_text( element_of_interest ))
    

    要获取有关原始文本之间边界的所有详细信息:

    class holder: pass # this is just a way of creating a holder object
    holder.element_count = 0
    def get_deep_text_w_boundaries(element, depth = 0):
        holder.element_count += 1
        element_no = holder.element_count 
        indent = depth * '  '
        text1 = f'{indent}(el {element_no} tag {element.tag}: text |{element.text or ""}| - attribs: {element.attrib})' 
        print(text1)
        for subelement in element:
            get_deep_text_w_boundaries(subelement, depth + 1)
        text2 = f'{indent}(el {element_no} tag {element.tag} - tail: |{element.tail or ""}|)' 
        print(text2)
    get_deep_text_w_boundaries(etree_element)
    

    示例输出:

    (el 1 tag source: text |DEVANT LE | - attribs: {})
      (el 2 tag g: text |TRIBUNAL JUDICIAIRE| - attribs: {'style_no': '3'})
      (el 2 tag g - tail: ||)
    (el 1 tag source - tail: | DE VERSAILLES|)
    

    【讨论】:

      【解决方案4】:

      我怀疑 ElementTree 是否可以用于此目的。但是假设您有充分的理由使用它,也许您可​​以尝试从片段中剥离根标签:

       re.sub(r'(^<%s\b.*?>|</%s\b.*?>$)' % (element.tag, element.tag), '', ElementTree.tostring(element))
      

      【讨论】:

        【解决方案5】:

        这里的大部分答案都是基于 XML 解析器 ElementTree,甚至 PEZ's regex-based answer 仍然部分依赖于 ElementTree。

        所有这些都很好并且适用于大多数用例,但为了完整起见,值得注意的是,ElementTree.tostring(...) 将为您提供等效的 sn-p,但并不总是与原始有效负载相同。如果出于某种非常罕见的原因,您想按原样提取内容,则必须使用纯正则表达式解决方案。 This example 是我使用基于正则表达式的解决方案的方式。

        【讨论】:

          【解决方案6】:

          此答案根据Pupeno 的 回复稍作修改。在这里,我将编码类型添加到“tostring”中。这个问题花了我好几个小时。我希望这个小的更正可以帮助其他人。

          def element_to_string(element):
                  s = element.text or ""
                  for sub_element in element:
                      s += ElementTree.tostring(sub_element, encoding='unicode')
                  s += element.tail
                  return s
          

          【讨论】:

            【解决方案7】:

            不知道是否可以选择外部库,但无论如何——假设页面上有一个带有此文本的&lt;p&gt;,jQuery 解决方案将是:

            alert($('p').html()); // returns blah <b>bleh</b> blih
            

            【讨论】:

              猜你喜欢
              • 2016-01-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-12-12
              • 2014-11-29
              • 2016-04-13
              相关资源
              最近更新 更多