Beautifulsoup 4:删除评论标签及其内容

时间:2014-04-25 17:34:34

标签: python html web-scraping html-parsing beautifulsoup

所以我正在报废的页面包含这些html代码。如何使用 bs4 删除评论标记<!-- -->及其内容?

<div class="foo">
cat dog sheep goat
<!-- 
<p>NewPP limit report
Preprocessor node count: 478/300000
Post‐expand include size: 4852/2097152 bytes
Template argument size: 870/2097152 bytes
Expensive parser function count: 2/100
ExtLoops count: 6/100
</p>
-->

</div>

4 个答案:

答案 0 :(得分:20)

您可以使用extract()(解决方案基于this answer):

  

PageElement.extract()从树中删除标记或字符串。它   返回提取的标记或字符串。

from bs4 import BeautifulSoup, Comment

data = """<div class="foo">
cat dog sheep goat
<!--
<p>test</p>
-->
</div>"""

soup = BeautifulSoup(data)

div = soup.find('div', class_='foo')
for element in div(text=lambda text: isinstance(text, Comment)):
    element.extract()

print soup.prettify()

结果导致您的div没有评论:

<div class="foo">
    cat dog sheep goat
</div>

答案 1 :(得分:5)

通常不需要修改bs4解析树。您可以获取div的文本,如果这是您想要的内容:

soup.body.div.text
Out[18]: '\ncat dog sheep goat\n\n'

bs4将评论分开。但是,如果您确实需要修改解析树:

from bs4 import Comment

for child in soup.body.div.children:
    if isinstance(child,Comment):
        child.extract()

答案 2 :(得分:0)

From this answer 如果您正在BeautifulSoup版本3 BS3 Docs - Comment

中寻找解决方案
soup = BeautifulSoup("""Hello! <!--I've got to be nice to get what I want.-->""")
comment = soup.find(text=re.compile("if"))
Comment=comment.__class__
for element in soup(text=lambda text: isinstance(text, Comment)):
    element.extract()
print soup.prettify()

答案 3 :(得分:0)

有点晚了,但我已经比较了互联网上的主要答案,因此您可以选择最适合您的:

我们也可以通过正则表达式删除评论

soupstr=str(soup)
result=re.sub(r'<!.*?->','', soupstr)

但是当我们通过 soupstr=str(soup) 将汤转换为字符串时,这种正则表达式方法比其他人编写的 findAll...isinstance(x,Comment) 慢 4 倍。

但是,当您将 html 作为字符串并应用正则表达式处理以删除注释时,速度会快 5 倍。

函数运行 1000 次后的基准测试结果:

bs4,isinstance(x,Comment) method: time: 0.01193189620971680ms
soup convert to string and apply regex: 0.04188799858093262ms
apply regex before converting to soup : 0.00195980072021484ms (WINNER!)

如果您不想使用 isinstance 方法,也许您可​​以使用纯正则表达式。

对于需要快速结果而又不想阅读完整答案的人,这里是准备运行的复制粘贴功能:

def remove_comments_regexmethod(soup): 
    #soup argument can be string or bs4.beautifulSoup instance it will auto convert to string, please prefer to input as (string) than (soup) if you want highest speed
    if not isinstance(soup,str): 
        soup=str(soup)
    return re.sub(r'<!.*?->','', soup)#returns a string