def remove_tags(dirty, allowed_tags=(), allowed_trees=(), strip=None):
if isinstance(dirty, six.string_types):<EOL><INDENT>element = etree.fromstring(u'<STR_LIT>'.join(('<STR_LIT>', dirty, '<STR_LIT>')))<EOL><DEDENT>elif isinstance(dirty, etree._Element):<EOL><INDENT>element = dirty<EOL><DEDENT>else:  <EOL><INDENT>element = dirty.root<EOL><DEDENT>if element.tag in allowed_trees:<EOL><INDENT>return etree.tostring(element, encoding='<STR_LIT>')<EOL><DEDENT>tail = element.tail or u'<STR_LIT>'<EOL>if strip and element.xpath(strip):<EOL><INDENT>return tail<EOL><DEDENT>subtext = u'<STR_LIT>'.join(<EOL>remove_tags(child, allowed_tags=allowed_tags, allowed_trees=allowed_trees, strip=strip)<EOL>for child in element<EOL>)<EOL>text = element.text or u'<STR_LIT>'<EOL>if element.tag in allowed_tags:<EOL><INDENT>for child in element:<EOL><INDENT>element.remove(child)<EOL><DEDENT>element.text = u'<STR_LIT>'.join((text, subtext))<EOL>return etree.tostring(element, encoding='<STR_LIT>')<EOL><DEDENT>return u'<STR_LIT>'.join((text, subtext, tail))<EOL>
Selectively remove tags.

    This removes all tags in ``dirty``, stripping also the contents of tags
    matching the XPath selector in ``strip``, and keeping all tags that are
    subtags of tags in ``allowed_trees`` and tags in ``allowed_tags``.

    Args:
        dirty(Union[str, scrapy.selector.Selector, lxml.etree._Element]): the
            input to clean up.
        allowed_tags(Container): tags to be kept in the output, but not necessarily
            its subtags.
        allowed_trees(Container): tags to be kept, along with all its subtags,
            in the output.
        strip(str): optional xpath selector. If it matches a tag, its
            contents will also be stripped. Useful axes are ``@`` for attribute access
            and ``self`` to select a given tag.

    Returns:
        str: the textual content of ``dirty``, with some tags kept and some text
        removed.

    Examples:
        >>> tag = '<p><b><i>Only</i></b> this text remains.<span class="hidden">Not this one.</span></p>'
        >>> remove_tags(tag, allowed_tree=('b',), strip='@class="hidden"')
        u'<b><i>Only</i></b> this text remains.'
        >>> remove_tags(tag, allowed_tags=('b',), strip='@class="hidden"')
        u'<b>Only</b> this text remains.'
        >>> remove_tags(tag, allowed_tags=('b',), strip='self::span')
        u'<b>Only</b> this text remains.'