2010-08-17 9 views
11

Ich habe mit BeautifulSoup gespielt, was großartig ist. Mein Endziel ist es zu versuchen, nur den Text von einer Seite zu bekommen. Ich versuche nur, den Text aus dem Körper zu bekommen, mit einem speziellen Fall, um den Titel und/oder alt-Attribute von <a> oder <img> Tags zu bekommen.Wie kann ich Kommentar-Tags aus HTML mit BeautifulSoup entfernen?

Bisher habe ich diese 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 

1) Was schlagen Sie den besten Weg für meinen speziellen Fall nicht, diese Attribute von den beiden Tags ausschließen ich oben aufgeführt? Wenn es zu komplex ist, um dies zu tun, ist es nicht so wichtig wie # 2.

2) Ich möchte <!-- --> Tags und alles dazwischen entfernen. Wie würde ich darüber gehen?

QUESTION EDIT @jathanism: Hier sind einige der Kommentar-Tags, die ich versucht habe, auszuziehen, aber bleiben, auch wenn ich dein Beispiel verwenden

<!-- 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() //--> 
+0

Gibt es ein Quelldokument, das Sie als Testfall verwenden? Es wäre sehr hilfreich, wenn Sie etwas zur Verfügung stellen könnten, das Ihnen als Vergleichsgrundlage dient. – jathanism

+0

Hinzugefügt Quelle mit zu spielen. – Nathan

Antwort

2

ich bin immer noch versuchen, herauszufinden, warum es nicht und Streifen-Tags wie diese findet: <!-- //-->. Diese Backslashes bewirken, dass bestimmte Tags übersehen werden.

Dies kann ein Problem mit dem zugrunde liegenden SGML-Parser sein: siehe http://www.crummy.com/software/BeautifulSoup/documentation.html#Sanitizing%20Bad%20Data%20with%20Regexps. Sie können es überschreiben, indem Sie eine markupMassage regex verwenden - direkt aus der Dokumentation:

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 
+1

Dies ist ein harter und das scheint ein guter Workaround zu sein. Traurig, dass es immer noch Regex verwendet, um HTML zu analysieren. Dummer Regex! – jathanism

+0

OK Ich werde an der re.compile arbeiten, um die verwirrten Kommentare zu finden, die ich aufgelistet habe. Müssen aber meine Regex auffrischen. blech. – Nathan

+0

@jathanism - BeautifulSoup verwendet intern mehrere Regexes, um das HTML zu polieren, bevor es in 'sgmllib' eingespeist wird. Es ist nicht schön, aber es ist auch nicht Lovecraftian. – katrielalex

53

Gerade vom documentation for BeautifulSoup, können Sie leicht abstreifen Kommentare (oder etwas) mit 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> 
+0

Ich weiß nicht, warum ich das nicht gesehen habe. Danke, dass du mich aufgeweckt hast! – Nathan

+5

Schön. Aber es sieht eklig aus, ein Listenverständnis mit Nebenwirkungen zu machen: p. Wie wäre es mit 'map (Lambda x: x.extract(), Kommentare)'? – katrielalex

+0

Ich versuche immer noch herauszufinden, warum es solche Tags nicht findet und entfernt. Diese Backslashes bewirken, dass bestimmte Tags übersehen werden – Nathan

Verwandte Themen