2012-10-18 9 views
8

Sto facendo un po 'di pulizia dell'HTML con BeautifulSoup. Noob to both Python & BeautifulSoup. Ho ottenuto i tag di essere rimosso correttamente come segue, in base a una risposta che ho trovato altrove sul StackOverflow:Rimuovi tutti gli stili in linea usando BeautifulSoup

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

Ma come rimuovere gli stili inline? Per esempio il seguente:

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

dovrebbe diventare:

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

Come eliminare le classi in linea, id, attributi nome & stile di tutti gli elementi?

Risposte ad altre domande simili Potrei trovare tutti citati usando un parser CSS per gestire questo, piuttosto che BeautifulSoup, ma poiché l'attività è semplicemente quella di rimuovere piuttosto che manipolare gli attributi, ed è una regola generale per tutti i tag, io speravo di trovare un modo per farlo tutto all'interno di BeautifulSoup.

risposta

25

Non è necessario analizzare alcun CSS se si desidera rimuovere tutto. BeautifulSoup fornisce un modo per rimuovere interi attributi in questo modo:

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

Inoltre, se si desidera solo per eliminare intere tag (ei loro contenuti), non è necessario extract(), che restituisce il tag. Hai solo bisogno decompose():

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

Non è una grande differenza, ma solo un'altra cosa che ho trovato mentre guardando i documenti. Puoi trovare maggiori dettagli sull'API nello BeautifulSoup documentation, con molti esempi.

+0

Stavo usando extract() nel caso in cui avessi deciso di generare un elenco di codice rimosso in qualsiasi momento, ma decompose() funziona altrettanto bene per rimuovere e distruggere completamente tag e contenuti. Grazie per lo snippet attribute-delete, funziona come un incantesimo! – Ila

+0

Ha senso. Lascerò la nota su 'decompose()' per chiunque altro possa inciampare in questo. – jmk

7

Non lo farei nello BeautifulSoup - passerai molto tempo a provare, testare e lavorare intorno ai casi limite.

Bleach fa esattamente questo per voi. http://pypi.python.org/pypi/bleach

Se dovessi farlo in BeautifulSoup, ti suggerirei di seguire l'approccio "lista bianca", come fa Bleach. Decidi quali tag possono avere quali attributi e elimina ogni tag/attributo che non corrisponde.

+0

Cool, non sapevo di Candeggina.Non stavo pensando al caso d'uso, ma se l'obiettivo è quello di disinfettare l'HTML non attendibile, questo sicuramente sembra un approccio migliore. Ottieni il mio upvote! – jmk

+0

La candeggina è molto bella. Mi piace veramente. –

1

sulla base della funzione di JMK, io uso questa funzione per rimuovere base di attributi in una lista bianca:

Work 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

Non si devono passare strutture mutabili come valori di parametri di funzione predefiniti. Come visto [qui] (http://effbot.org/zone/default-values.htm). –

0

Ecco la mia soluzione per python3 e 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 

Supporta una whitelist di attributi che devono essere mantenuti. :) Se non viene fornita nessuna lista bianca, tutti gli attributi vengono rimossi.