如何使用BeautifulSoup从HTML中删除注释标记?

Nat*_*han 13 python beautifulsoup

我一直在玩BeautifulSoup,这很棒.我的最终目标是尝试从页面中获取文本.我只是想从正文文本,用特制的情况下拿到冠军和/或ALT属性从<a><img>标签.

到目前为止我有这个EDITED & UPDATED CURRENT CODE:

soup = BeautifulSoup(page)
comments = soup.findAll(text=lambda text:isinstance(text, Comment))
[comment.extract() for comment in comments]
page = ''.join(soup.findAll(text=True))
page = ' '.join(page.split())
print page
Run Code Online (Sandbox Code Playgroud)

1)你有什么建议我的特殊情况的最好方法是不从上面列出的两个标签中排除这些属性?如果它太复杂而不能做到这一点,那就不像做#2那么重要了.

2)我想剥离<!-- -->标签和它们之间的一切.我该怎么办呢?

QUESTION EDIT @jathanism:这里有一些注释标签,我试图去除,但仍然存在,即使我使用你的例子

<!-- Begin function popUp(URL) { day = new Date(); id = day.getTime(); eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=300,height=330,left = 774,top = 518');"); } // End -->
<!-- var MenuBar1 = new Spry.Widget.MenuBar("MenuBar1", {imgDown:"SpryAssets/SpryMenuBarDownHover.gif", imgRight:"SpryAssets/SpryMenuBarRightHover.gif"}); //--> <!-- var MenuBar1 = new Spry.Widget.MenuBar("MenuBar1", {imgDown:"SpryAssets/SpryMenuBarDownHover.gif", imgRight:"SpryAssets/SpryMenuBarRightHover.gif"}); //--> <!-- var whichlink=0 var whichimage=0 var blenddelay=(ie)? document.images.slide.filters[0].duration*1000 : 0 function slideit(){ if (!document.images) return if (ie) document.images.slide.filters[0].apply() document.images.slide.src=imageholder[whichimage].src if (ie) document.images.slide.filters[0].play() whichlink=whichimage whichimage=(whichimage<slideimages.length-1)? whichimage+1 : 0 setTimeout("slideit()",slidespeed+blenddelay) } slideit() //-->
Run Code Online (Sandbox Code Playgroud)

jat*_*ism 59

直接来自BeautifulSoup文档,您可以使用以下方法轻松删除注释(或任何内容)extract():

from BeautifulSoup import BeautifulSoup, Comment
soup = BeautifulSoup("""1<!--The loneliest number-->
                        <a>2<!--Can be as bad as one--><b>3""")
comments = soup.findAll(text=lambda text:isinstance(text, Comment))
[comment.extract() for comment in comments]
print soup
# 1
# <a>2<b>3</b></a>
Run Code Online (Sandbox Code Playgroud)

  • 尼斯.但是,通过副作用进行列表理解看起来很蹩脚:p.如何`map(lambda x:x.extract(),comments)` (5认同)

Kat*_*iel 3

我仍在试图找出为什么它找不到并删除这样的标签: <!-- //-->。这些反斜杠会导致某些标签被忽略。

这可能是底层 SGML 解析器的问题:请参阅http://www.crummy.com/software/BeautifulSoup/documentation.html#Sanitizing%20Bad%20Data%20with%20Regexps。您可以使用markupMassage正则表达式来覆盖它——直接来自文档:

import re, copy

myMassage = [(re.compile('<!-([^-])'), lambda match: '<!--' + match.group(1))]
myNewMassage = copy.copy(BeautifulSoup.MARKUP_MASSAGE)
myNewMassage.extend(myMassage)

BeautifulSoup(badString, markupMassage=myNewMassage)
# Foo<!--This comment is malformed.-->Bar<br />Baz
Run Code Online (Sandbox Code Playgroud)

  • 只是为了更新这篇旧文章,BeautifulSoup.MARKUP_MASSAGE 已被弃用。“BeautifulSoup 构造函数不再识别 markupMassage 参数。现在解析器有责任正确处理标记。” http://www.crummy.com/software/BeautifulSoup/bs4/doc/(在页面的最底部) (4认同)
  • 这是一个困难的问题,但这看起来是一个很好的解决方法。遗憾的是它最终仍然使用正则表达式来解析 HTML。愚蠢的正则表达式! (2认同)