BeautifulSoup4 提取所有类型的条件注释
BeautifulSoup4 extract all types of conditional comments
我尝试做的事情:
使用 bs4 从 html 邮件中删除可疑评论。现在我遇到了所谓 conditional comments
类型 downlevel-revealed
的问题。
import bs4
html = 'A<!--[if expression]>a<![endif]-->' \
'B<![if expression]>b<![endif]>'
soup = bs4.BeautifulSoup(html, 'html5lib')
for comment in soup.find_all(text=lambda text: isinstance(text, bs4.Comment)):
comment.extract()
提取评论前:
'A',
'[if expression]>a<![endif]',
'B',
'[if expression]',
'b',
'[endif]',
提取评论后:
'A',
'B',
'b',
问题:
小b也要去掉。问题是,bs4 将第一个评论检测为单个评论对象,但第二个评论检测为 3 个对象。 Comment(if)、NavigableString(b) 和 Comment(endif)。提取只是删除这两种评论类型。内容为 'b' 的 NavigableString 保留在 DOM.
中
有解决办法吗?
经过一段时间阅读条件注释后,我可以理解为什么会这样。
下层隐藏
downlevel-hidden
基本都是写成普通注释<!-- ... -->
。这在现代浏览器中被检测为条件注释块。因此,如果我想删除条件注释,BeautifulSoup 会完全删除它。
下层透露
downlevel-revealed
写成<!...>b<!...>
,现代浏览器检测到这两个标签无效并在DOM中忽略它们,所以只有b
仍然有效。所以 BeautifulSoup 只删除标签,不删除内容
结论
BeautifulSoup 像现代浏览器一样处理条件注释。这对我的情况来说完全没问题。
我尝试做的事情:
使用 bs4 从 html 邮件中删除可疑评论。现在我遇到了所谓 conditional comments
类型 downlevel-revealed
的问题。
import bs4
html = 'A<!--[if expression]>a<![endif]-->' \
'B<![if expression]>b<![endif]>'
soup = bs4.BeautifulSoup(html, 'html5lib')
for comment in soup.find_all(text=lambda text: isinstance(text, bs4.Comment)):
comment.extract()
提取评论前:
'A',
'[if expression]>a<![endif]',
'B',
'[if expression]',
'b',
'[endif]',
提取评论后:
'A',
'B',
'b',
问题:
小b也要去掉。问题是,bs4 将第一个评论检测为单个评论对象,但第二个评论检测为 3 个对象。 Comment(if)、NavigableString(b) 和 Comment(endif)。提取只是删除这两种评论类型。内容为 'b' 的 NavigableString 保留在 DOM.
中有解决办法吗?
经过一段时间阅读条件注释后,我可以理解为什么会这样。
下层隐藏
downlevel-hidden
基本都是写成普通注释<!-- ... -->
。这在现代浏览器中被检测为条件注释块。因此,如果我想删除条件注释,BeautifulSoup 会完全删除它。
下层透露
downlevel-revealed
写成<!...>b<!...>
,现代浏览器检测到这两个标签无效并在DOM中忽略它们,所以只有b
仍然有效。所以 BeautifulSoup 只删除标签,不删除内容
结论
BeautifulSoup 像现代浏览器一样处理条件注释。这对我的情况来说完全没问题。