2012-11-12 7 views
26

Ich versuche, ein Stück HTML-Text mit BeautifulSoup zu konvertieren. Hier ein Beispiel:Gerendertes HTML in Klartext mit 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> 

Ich habe versucht, etwas zu tun, wie:

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) 

... aber auf diese Weise meines span-Element ist immer auf eine neue Zeile. Dies ist natürlich ein einfaches Beispiel. Gibt es eine Möglichkeit, den Text in der HTML-Seite so zu erhalten, wie er im Browser gerendert wird (keine CSS-Regeln erforderlich, nur die normalen Methoden wie div, span, li, usw.) in Python?

Antwort

61

BeautifulSoup ist eine Scraping-Bibliothek, daher ist es wahrscheinlich nicht die beste Wahl für HTML-Rendering. Wenn BeautifulSoup nicht unbedingt erforderlich ist, sollten Sie sich html2text ansehen. Zum Beispiel:

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

Diese Ausgänge:

 
Some text more text even more text 

    * list item 
    * yet another list item 

Some other text 

    * list item 
    * yet another list item 
+1

Kann ich html2text in Verbindung mit BeautifulSoup verwenden. Zum Beispiel analysiere ich das Stück HTML, das mich interessiert, und füttere es dann mit pretify() in html2text? – btatarov

+1

Ja, html2text kann HTML in Chunks verarbeiten, indem es 'HTML2Text.feed (chunk)' auf jedem nachfolgenden Chunk aufruft und dann 'HTML2Text.close()' aufruft, um das Textergebnis zu erhalten (ähnlich wie bei '' HTMLParser.feed() ') ] (http://docs.python.org/2/library/htmlparser.html#HTMLParser.HTMLParser.feed)). – del

+11

Diese Antwort hat mich glücklich und traurig zugleich gemacht. RIP Aaron Swartz. –

2

Ich war das gleiche Problem zu begegnen versucht, das gerenderte HTML zu analysieren. Grundsätzlich scheint BS nicht das ideale Paket dafür zu sein. @Del gibt die großartige html2text Lösung.

Auf einer anderen SO Frage: BeautifulSoup get_text does not strip all tags and JavaScript @Helge mit Nltk erwähnt. Leider scheint nltk diese Methode aufzugeben.

Ich habe sowohl html2text als auch nltk.clean_html ausprobiert und war überrascht von den Timing-Ergebnissen, also dachten sie, dass sie eine Antwort für die Nachwelt boten. Natürlich hängen die Geschwindigkeiten stark vom Inhalt der Daten ab ...

Antwort von @Helge (nltk).

import nltk 

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

Es funktionierte wirklich gut, um eine Zeichenfolge mit gerenderten HTML zurückzugeben. Dieses nltk-Modul war schneller als html2text, obwohl vielleicht html2text robuster ist.

Antwort oben von @del

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

nltk.clean_html gibt 'NotImplementedError: Um HTML Markup zu entfernen, benutze BeautifulSoup's Funktion get_text() –

+2

Auch wenn du eine alte Version von nltk hast, benutze diese Funktion nicht. Es ist schnell, weil es HTML mit Regexen verarbeitet: https://github.com/nltk/nltk/blob/e86e83b1e2219fb099c4fbcff89a4ae07cd14868/nltk/util.py#L333-L353 – digenishjkl

+1

Ich fügte eine Antwort auf eine verwandte Frage hinzu, die eine Möglichkeit gibt, JavaScript zu strippen über BeautifulSoup: https://Stackoverflow.com/a/47782943/2112722 –