2012-11-12 24 views
26

Próbuję przekonwertować fragment tekstu HTML z BeautifulSoup. Oto przykład:Renderowany HTML do zwykłego tekstu za pomocą Pythona

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

Próbowałem robić coś takiego:

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) 

... ale w ten sposób mój żywioł rozpiętość jest zawsze w nowej linii. Jest to oczywiście prosty przykład. Czy istnieje sposób na uzyskanie tekstu na stronie HTML w taki sposób, w jaki będzie renderowany w przeglądarce (bez wymaganych reguł css, po prostu w sposób normalny renderowane elementy div, span, li itp.) W Pythonie?

Odpowiedz

61

BeautifulSoup to biblioteka do skrobania, więc prawdopodobnie nie jest najlepszym wyborem do renderowania HTML. Jeśli nie jest konieczne używanie BeautifulSoup, powinieneś spojrzeć na html2text. Na przykład:

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

Ten Wyjścia:

 
Some text more text even more text 

    * list item 
    * yet another list item 

Some other text 

    * list item 
    * yet another list item 
+1

mogę używać html2text w zbiegu z BeautifulSoup. Na przykład analizuję fragment html, który mnie interesuje, a następnie przekazuję go do html2text za pomocą pretify()? – btatarov

+1

Tak, html2text może przetwarzać HTML w porcjach, wywołując 'HTML2Text.feed (chunk)' na każdej kolejnej porcji, a następnie wywołując 'HTML2Text.close()', aby uzyskać wynik tekstowy (podobny do ['HTMLParser.feed()' ] (http://docs.python.org/2/library/htmlparser.html#HTMLParser.HTMLParser.feed)). – del

+11

Ta odpowiedź sprawiła, że ​​byłem szczęśliwy i smutny w tym samym czasie. RIP Aaron Swartz. –

2

byłem napotykają ten sam problem próbuje zanalizować renderowany HTML. Zasadniczo wydaje się, że BS nie jest idealnym pakietem do tego. @Del daje świetne rozwiązanie html2text.

Na różne pytania SO: BeautifulSoup get_text does not strip all tags and JavaScript @Helge wymienione przy użyciu nltk. Niestety nltk wydaje się zaprzestać tej metody.

Próbowałem zarówno html2text, jak i nltk.clean_html i byłem zaskoczony wynikami taktowania, więc uważam, że uzasadniły one odpowiedź dla potomności. Oczywiście prędkości zależą w dużej mierze od zawartości danych ...

Odpowiedź od @Helge (nltk).

import nltk 

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

Naprawdę dobrze działało, aby zwrócić ciąg z renderowanym html. Ten moduł nltk był szybszy niż nawet html2text, chociaż prawdopodobnie html2text jest bardziej niezawodny.

Odpowiedź wyżej od @del

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

nltk.clean_html daje 'NotImplementedError: Aby usunąć znaczniki HTML, użyj funkcji get_text() BeautifulSoup'' –

+2

Nawet jeśli masz starą wersję nltk, nie używaj tej funkcji. Jest szybki, ponieważ przetwarza html z wyrażeń regularnych: https://github.com/nltk/nltk/blob/e86e83b1e2219fb099c4fbcff89a4ae07cd14868/nltk/util.py#L333-L353 – digenishjkl

+1

Dodałem odpowiedź na pokrewne pytanie, które daje sposób na usunięcie JavaScript przez BeautifulSoup: https://stackoverflow.com/a/47782943/2112722 –

Powiązane problemy