如何从没有尾部的lxml中的节点中删除标签?

时间:2017-03-21 16:23:07

标签: python beautifulsoup html-parsing lxml

示例:

html = <a><b>Text</b>Text2</a>

BeautifullSoup代码

[x.extract() for x in html.findAll(.//b)]

退出时我们有:

html = <a>Text2</a>

Lxml代码:

[bad.getparent().remove(bad) for bad in html.xpath(".//b")]

退出时我们有:

html = <a></a>

因为lxml认为&#34; Text2&#34;它是<b></b>

的尾巴

如果我们只需要连接标签的文字行,我们就可以使用:

for bad in raw.xpath(xpath_search):
    bad.text = ''

但是,如何在不更改文本的情况下执行此操作,但删除没有尾部的标记?

2 个答案:

答案 0 :(得分:6)

虽然phlou接受的答案可行,但有更简单的方法可以在不删除标签的情况下删除标签。

如果要删除特定元素,那么您要查找的LXML方法是drop_tree

来自文档:

  

删除元素及其所有子元素。与el.getparent()。remove(el)不同,这不会删除尾部文本;使用drop_tree,尾部文本与前一个元素合并。

如果您要删除特定代码的所有实例,可以使用lxml.etree.strip_elementslxml.html.etree.strip_elements withtails=False

  

使用树或提供的标记名称删除所有元素   子树。这将删除元素及其整个子树,   包括他们的所有属性,文本内容和后代。它   除非你,否则也将删除元素的尾部文本   将with_tail关键字参数选项显式设置为False。

所以,对于原帖中的例子:

>>> from lxml.html import fragment_fromstring, tostring
>>>
>>> html = fragment_fromstring('<a><b>Text</b>Text2</a>')
>>> for bad in html.xpath('.//b'):
...    bad.drop_tag()
>>> tostring(html)
'<a>Text2</a>'

>>> from lxml.html import fragment_fromstring, tostring, etree
>>>
>>> html = fragment_fromstring('<a><b>Text</b>Text2</a>')
>>> etree.strip_elements(html, 'b', with_tail=False)
>>> tostring(html)
'<a>Text2</a>'

答案 1 :(得分:4)

我执行了以下操作以将尾部文本保护到上一个兄弟或父母。

def remove_keeping_tail(self, element):
    """Safe the tail text and then delete the element"""
    self._preserve_tail_before_delete(element)
    element.getparent().remove(element)

def _preserve_tail_before_delete(self, node):
    if node.tail: # preserve the tail
        previous = node.getprevious()
        if previous is not None: # if there is a previous sibling it will get the tail
            if previous.tail is None:
                previous.tail = node.tail
            else:
                previous.tail = previous.tail + node.tail
        else: # The parent get the tail as text
            parent = node.getparent()
            if parent.text is None:
                parent.text = node.tail
            else:
                parent.text = parent.text + node.tail

HTH