Rendu HTML à du texte brut en utilisant Python

j'essaie de convertir un morceau de texte HTML avec BeautifulSoup. Voici un exemple:

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

j'ai essayé de faire quelque chose comme:

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

...mais de cette façon, mon élément span est toujours sur une nouvelle ligne. Bien sûr, ceci est un simple exemple. Y a-t-il un moyen d'obtenir le texte dans la page HTML de la façon dont il sera rendu dans le navigateur (pas de règles css nécessaires, juste la manière habituelle div, span, li, etc. les éléments sont rendus) en Python?

30
demandé sur btatarov 2012-11-12 06:06:34

2 réponses

BeautifulSoup est une bibliothèque de grattage, donc ce n'est probablement pas le meilleur choix pour faire le rendu HTML. S'il n'est pas essentiel D'utiliser BeautifulSoup, vous devriez jeter un oeil à html2text . Par exemple:

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

Ce sorties:

Some text more text even more text

  * list item
  * yet another list item

Some other text

  * list item
  * yet another list item
68
répondu del 2012-11-12 03:09:46

j'ai rencontré le même problème en essayant de parser le HTML rendu. Fondamentalement, il semble que BS n'est pas le paquet idéal pour cela. @Del donne la grande solution html2text.

sur une question différente ainsi: BeautifulSoup get_text ne supprime pas toutes les balises et JavaScript @Helge mentionné en utilisant nltk. Malheureusement, nltk semble abandonner cette méthode.

j'ai essayé à la fois html2text et nltk.clean_html et a été surpris par les résultats de timing donc pensé qu'ils justifiaient une réponse pour la postérité. Bien sûr, les vitesses dépendent fortement du contenu des données...

réponse de @Helge (nltk).

import nltk

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

cela fonctionnait vraiment bien pour retourner une chaîne de caractères Avec rendu html. Ce module nltk était plus rapide que même html2text, bien que html2text soit peut-être plus robuste.

réponse ci-dessus de @del

betterHTML = html.decode(errors='ignore')
%timeit html2text.html2text(betterHTML)
%3.09 ms per loop
2
répondu Paul 2017-05-23 12:02:46