2012-11-12 20 views
26

Sto provando a convertire un blocco di testo HTML con BeautifulSoup. Ecco un esempio:HTML reso a testo normale usando Python

<div> 
    <p> 
     Some text 
     <span>more text</span> 
     even more text 
    </p> 
    <ul> 
     <li>list item</li> 
     <li>yet another list item</li> 
    </ul> 
</div> 
<p>Some other text</p> 
<ul> 
    <li>list item</li> 
    <li>yet another list item</li> 
</ul> 

Ho provato a fare qualcosa di simile:

def parse_text(contents_string) 
    Newlines = re.compile(r'[\r\n]\s+') 
    bs = BeautifulSoup.BeautifulSoup(contents_string, convertEntities=BeautifulSoup.BeautifulSoup.HTML_ENTITIES) 
    txt = bs.getText('\n') 
    return Newlines.sub('\n', txt) 

... ma in questo modo il mio elemento di calibrazione è sempre su una nuova linea. Questo è ovviamente un semplice esempio. C'è un modo per ottenere il testo nella pagina HTML come il modo in cui sarà reso nel browser (non sono richieste le regole CSS, solo il modo regolare renderizza gli elementi div, span, li, ecc.) In Python?

risposta

61

BeautifulSoup è una libreria di scraping, quindi probabilmente non è la scelta migliore per eseguire il rendering HTML. Se non è essenziale utilizzare BeautifulSoup, è necessario dare un'occhiata a html2text. Ad esempio:

import html2text 
html = open("foobar.html").read() 
print html2text.html2text(html) 

Questo fornisce in uscita:

 
Some text more text even more text 

    * list item 
    * yet another list item 

Some other text 

    * list item 
    * yet another list item 
+1

Posso usare html2text in raccordo con BeautifulSoup. Ad esempio, analizzo il pezzo di HTML che mi interessa e lo trasmetto a html2text usando pretify()? – btatarov

+1

Sì, html2text può elaborare l'HTML in blocchi chiamando 'HTML2Text.feed (chunk)' su ciascun blocco successivo, quindi chiamando 'HTML2Text.close()' per ottenere il risultato del testo (simile a ['HTMLParser.feed()' ] (http://docs.python.org/2/library/htmlparser.html#HTMLParser.HTMLParser.feed)). – del

+11

Questa risposta mi ha reso felice e triste allo stesso tempo. RIP Aaron Swartz. –

2

ero incontrando lo stesso problema cercando di analizzare il rendering HTML. Fondamentalmente sembra che BS non sia il pacchetto ideale per questo. @Del offre la grande soluzione html2text.

Su una domanda SO diversa: BeautifulSoup get_text does not strip all tags and JavaScript @Helge menzionato utilizzando nltk. Sfortunatamente nltk sembra stia cessando questo metodo.

Ho provato entrambi html2text e nltk.clean_html e sono rimasto sorpreso dai risultati del cronometraggio, quindi ho pensato di giustificare una risposta per i posteri. Ovviamente le velocità dipendono molto dal contenuto dei dati ...

Risposta da @Helge (nltk).

import nltk 

%timeit nltk.clean_html(html) 
was returning 153 us per loop 

Ha funzionato molto bene per restituire una stringa con il rendering html. Questo modulo nltk era più veloce persino di html2text, anche se forse html2text è più robusto.

risposta sopra da @del

betterHTML = html.decode(errors='ignore') 
%timeit html2text.html2text(betterHTML) 
%3.09 ms per loop 
+8

nltk.clean_html fornisce 'NotImplementedError: Per rimuovere il markup HTML, utilizzare la funzione get_text() di BeautifulSoup' –

+2

Anche se si dispone di una versione precedente di nltk, non utilizzare questa funzione. È veloce perché elabora html con espressioni regolari: https://github.com/nltk/nltk/blob/e86e83b1e2219fb099c4fbcff89a4ae07cd14868/nltk/util.py#L333-L353 – digenishjkl

+1

Ho aggiunto una risposta a una domanda correlata che offre un modo per eliminare JavaScript tramite BeautifulSoup: https://stackoverflow.com/a/47782943/2112722 –

Problemi correlati