我正在使用http://lxml.de/库解析HTML文档。到目前为止,我已经知道如何从HTML文档中删除标签 (在lxml中,如何删除标签但保留所有内容?),但是该帖子中描述的方法会保留所有文本,而不是将脚本标签移除。我还找到了一个class reference,名为lxml.html.clean.Cleaner (http://lxml.de/api/lxml.html.clean.Cleaner-class.html),但是这个类如何使用并不清楚。任何帮助,也许一个简短的例子对我会有用!
我正在使用http://lxml.de/库解析HTML文档。到目前为止,我已经知道如何从HTML文档中删除标签 (在lxml中,如何删除标签但保留所有内容?),但是该帖子中描述的方法会保留所有文本,而不是将脚本标签移除。我还找到了一个class reference,名为lxml.html.clean.Cleaner (http://lxml.de/api/lxml.html.clean.Cleaner-class.html),但是这个类如何使用并不清楚。任何帮助,也许一个简短的例子对我会有用!
以下是一个示例,可以实现你想要的功能。对于HTML文档,Cleaner
是解决这个问题比使用strip_elements
更好的通用解决方案,因为在这种情况下,你想要剥离的不仅仅是<script>
标记;还需要摆脱其他标记上的onclick=function()
属性等内容。
#!/usr/bin/env python
import lxml
from lxml.html.clean import Cleaner
cleaner = Cleaner()
cleaner.javascript = True # This is True because we want to activate the javascript filter
cleaner.style = True # This is True because we want to activate the styles & stylesheet filter
print("WITH JAVASCRIPT & STYLES")
print(lxml.html.tostring(lxml.html.parse('http://www.google.com')))
print("WITHOUT JAVASCRIPT & STYLES")
print(lxml.html.tostring(cleaner.clean_html(lxml.html.parse('http://www.google.com'))))
您可以在lxml.html.clean.Cleaner文档中获取可设置的选项列表; 有些选项可以直接设置为True
或False
(默认值),而其他选项需要使用类似以下方式的列表:cleaner.kill_tags = ['a', 'h1']
cleaner.remove_tags = ['p']
请注意kill和remove之间的区别:
remove_tags:
A list of tags to remove. Only the tags will be removed, their content will get pulled up into the parent tag.
kill_tags:
A list of tags to kill. Killing also removes the tag's content, i.e. the whole subtree, not just the tag itself.
allow_tags:
A list of tags to include (default include all).
# (REMOVE <SCRIPT> to </script> and variations)
pattern = r'<[ ]*script.*?\/[ ]*script[ ]*>' # mach any char zero or more times
text = re.sub(pattern, '', text, flags=(re.IGNORECASE | re.MULTILINE | re.DOTALL))
# (REMOVE HTML <STYLE> to </style> and variations)
pattern = r'<[ ]*style.*?\/[ ]*style[ ]*>' # mach any char zero or more times
text = re.sub(pattern, '', text, flags=(re.IGNORECASE | re.MULTILINE | re.DOTALL))
# (REMOVE HTML <META> to </meta> and variations)
pattern = r'<[ ]*meta.*?>' # mach any char zero or more times
text = re.sub(pattern, '', text, flags=(re.IGNORECASE | re.MULTILINE | re.DOTALL))
# (REMOVE HTML COMMENTS <!-- to --> and variations)
pattern = r'<[ ]*!--.*?--[ ]*>' # mach any char zero or more times
text = re.sub(pattern, '', text, flags=(re.IGNORECASE | re.MULTILINE | re.DOTALL))
# (REMOVE HTML DOCTYPE <!DOCTYPE html to > and variations)
pattern = r'<[ ]*\![ ]*DOCTYPE.*?>' # mach any char zero or more times
text = re.sub(pattern, '', text, flags=(re.IGNORECASE | re.MULTILINE | re.DOTALL))
注意:
re.IGNORECASE # is needed to match case sensitive <script> or <SCRIPT> or <Script>
re.MULTILINE # is needed to match newlines
re.DOTALL # is needed to match "special characters" and match "any character"
`、`
您可以使用strip_elements方法来删除脚本,然后使用strip_tags方法来删除其他标签:
etree.strip_elements(fragment, 'script')
etree.strip_tags(fragment, 'a', 'p') # and other tags that you want to remove
<script>
标签本身,因此 Cleaner 是一个更好的通用解决方案(https://dev59.com/4moy5IYBdhLWcg3wcNhO#8554251),尽管 strip_elements
对于 XML 文档也可以。 - aculichsoup = BeautifulSoup(html_src, "lxml")
[x.extract() for x in soup.findAll(['script', 'style'])]
soup
的内容。也就是说,soup
不再具有这些标签。 - havlock您可以轻松使用正则表达式
对于JavaScript
def remove_script_code(data):
clean = re.compile('<script>.*?</script>')
return [re.sub(clean, '', data)]
关于 CSS 样式
def remove_style_code(data):
clean = re.compile('<style>.*?</style>')
return [re.sub(clean, '', data)]
cleaner.kill_tags = ('img','noscript','a')
,但是这些标签仍然存在于输出文档中,上面的其余示例按预期工作,只是在玩弄 kill tags 后我才注意到这一点。 - john-charles['img','noscript','a']
。方括号表示列表,而圆括号表示元组(在您的示例中为3个元素的元组)。元组和列表完全不同。 - aculich,而在Ubuntu版本的clean.py中,它仅被初始化为
kill_tags = set()`。这使其无效。谢谢,我会通知软件包维护者。 - john-charles