2012-10-18 18 views
8

Ich mache einige HTML-Reinigung mit BeautifulSoup. Noob zu beiden Python & BeautifulSoup. Ich habe Tags werde ich an anderer Stelle gefunden auf Stackoverflow korrekt wie folgt auf der Grundlage eine Antwort entfernt:Entfernen Sie alle Inline-Stile mit BeautifulSoup

[s.extract() for s in soup('script')] 

Aber wie Inline-Stile entfernen? Zum Beispiel die folgende:

<p class="author" id="author_id" name="author_name" style="color:red;">Text</p> 
<img class="some_image" href="somewhere.com"> 

werden sollte:

<p>Text</p> 
<img href="somewhere.com"> 

Wie die Inline-Klasse, ID, Name & Stil Attribute aller Elemente löschen?

Antworten auf andere ähnliche Fragen Ich könnte alle erwähnt mit einem CSS-Parser, um dies statt BeautifulSoup, sondern als die Aufgabe zu finden ist einfach zu entfernen, anstatt die Attribute zu manipulieren, und ist eine allgemeine Regel für alle Tags, ich hoffte, einen Weg zu finden, alles innerhalb von BeautifulSoup zu tun.

Antwort

25

Sie müssen kein CSS analysieren, wenn Sie nur alles entfernen möchten. BeautifulSoup bietet eine Möglichkeit, wie so ganze Attribute zu entfernen:

for tag in soup(): 
    for attribute in ["class", "id", "name", "style"]: 
     del tag[attribute] 

Auch wenn Sie nur ganze Tags löschen möchten (und deren Inhalt), die Sie nicht extract() benötigen, die das Tag zurückgibt. Sie müssen nur decompose():

[tag.decompose() for tag in soup("script")] 

keine großen Unterschied, aber nur etwas anderes fand ich, während bei der Dokumentation suchen. Sie können mehr Details über die API in der BeautifulSoup documentation finden, mit vielen Beispielen.

+0

Ich benutzte extract() für den Fall, dass ich entschied, eine Liste von entferntem Code zu einem beliebigen Zeitpunkt zu erstellen, aber decompose() funktioniert genauso gut für die vollständige Entfernung und Zerstörung von Tags und Inhalten. Danke für das Attribut-Löschen-Snippet, funktioniert wie ein Zauber! – Ila

+0

Sinn macht. Ich werde die Notiz über 'decompose()' für jeden anderen hinterlassen, der darüber stolpern könnte. – jmk

7

Ich würde dies nicht tun in BeautifulSoup - Sie werden eine Menge Zeit verbringen versuchen, testen und arbeiten Randfälle.

Bleach macht genau das für Sie. Wenn Sie dies in BeautifulSoup tun würden, würde ich vorschlagen, dass Sie mit der "Whitelist" -Ansatz gehen, wie Bleach tut. Entscheiden Sie, welche Tags welche Attribute haben sollen, und entfernen Sie alle Tags/Attribute, die nicht übereinstimmen.

+0

Cool, ich wusste nichts über Bleach.Ich habe nicht an den Anwendungsfall gedacht, aber wenn es darum geht, nicht vertrauenswürdiges HTML zu bereinigen, dann scheint dies definitiv ein besserer Ansatz zu sein. Du bekommst mein Lob! – jmk

+0

Bleach ist ziemlich gut. Ich mag es wirklich. –

1

Basierend auf jmk der Funktion, i diese Funktion verwenden, um Attribute Basis auf einer weißen Liste zu entfernen:

Arbeit in python2, BeautifulSoup3

def clean(tag,whitelist=[]): 
    tag.attrs = None 
    for e in tag.findAll(True): 
     for attribute in e.attrs: 
      if attribute[0] not in whitelist: 
       del e[attribute[0]] 
     #e.attrs = None  #delte all attributes 
    return tag 

#example to keep only title and href 
clean(soup,["title","href"]) 
+0

Sie sollten keine veränderbaren Strukturen als Standardfunktionsparameterwerte übergeben. Wie gesehen [hier] (http://effbot.org/zone/default-values.htm). –

0

Hier ist meine Lösung für Python3 und BeautifulSoup4:

def remove_attrs(soup, whitelist=tuple()): 
    for tag in soup.findAll(True): 
     for attr in [attr for attr in tag.attrs if attr not in whitelist]: 
      del tag[attr] 
    return soup 

Es unterstützt eine Whitelist von Attributen, die beibehalten werden sollten. :) Wenn keine Whitelist angegeben wird, werden alle Attribute entfernt.

Verwandte Themen