使用html5lib或bleach删除<style> ... </style>标记的内容

时间:2011-09-24 11:00:47

标签: python django html5lib

我一直在使用优秀的bleach库删除错误的HTML。

我已经从Microsoft Word粘贴了大量HTML文档,其中包含以下内容:

<STYLE> st1:*{behavior:url(#ieooui) } </STYLE>

使用漂白(隐式禁止style标记),请留下:

st1:*{behavior:url(#ieooui) }

哪个没用。 Bleach似乎只有以下选项:

  • 转义标签;
  • 删除标签(但不删除其内容)。

我正在寻找第三个选项 - 删除标签及其内容。

有没有办法使用漂白或html5lib来完全删除style标签及其内容? documentation for html5lib并没有太大的帮助。

2 个答案:

答案 0 :(得分:5)

事实证明lxml是完成此任务的更好工具:

from lxml.html.clean import Cleaner

def clean_word_text(text):
    # The only thing I need Cleaner for is to clear out the contents of
    # <style>...</style> tags
    cleaner = Cleaner(style=True)
    return cleaner.clean_html(text)

答案 1 :(得分:1)

我能够使用基于这种方法的过滤器去除标签的内容:https://bleach.readthedocs.io/en/latest/clean.html?highlight=strip#html5lib-filters-filters。它确实在输出中留下了一个空的 <style></style>,但这是无害的。

from bleach.sanitizer import Cleaner
from bleach.html5lib_shim import Filter

class StyleTagFilter(Filter):
    """
    https://bleach.readthedocs.io/en/latest/clean.html?highlight=strip#html5lib-filters-filters
    """

    def __iter__(self):
        in_style_tag = False
        for token in Filter.__iter__(self):
            if token["type"] == "StartTag" and token["name"] == "style":
                in_style_tag = True
            elif token["type"] == "EndTag":
                in_style_tag = False
            elif in_style_tag:
                # If we are in a style tag, strip the contents
                token["data"] = ""
            yield token


# You must include "style" in the tags list
cleaner = Cleaner(tags=["div", "style"], strip=True, filters=[StyleTagFilter])
cleaned = cleaner.clean("<div><style>.some_style { font-weight: bold; }</style>Some text</div>")

assert cleaned == "<div><style></style>Some text</div>"