Extraire du texte d'un fichier HTML à l'aide de Python

243

Je voudrais extraire le texte d'un fichier HTML en utilisant Python. Je veux essentiellement la même sortie que j'obtiendrais si je copiais le texte à partir d'un navigateur et le collais dans le bloc-notes.

J'aimerais quelque chose de plus robuste que d'utiliser des expressions régulières qui peuvent échouer sur du HTML mal formé. J'ai vu beaucoup de gens recommander Beautiful Soup, mais j'ai eu quelques problèmes à l'utiliser. D'une part, il a récupéré du texte indésirable, comme une source JavaScript. En outre, il n'a pas interprété les entités HTML. Par exemple, je m'attendrais à & # 39; dans la source HTML à convertir en apostrophe dans le texte, comme si j'avais collé le contenu du navigateur dans le bloc-notes.

La mise à jour html2text semble prometteuse. Il gère correctement les entités HTML et ignore JavaScript. Cependant, il ne produit pas exactement du texte brut; il produit une démarque qui devrait ensuite être transformée en texte brut. Il est livré sans exemples ni documentation, mais le code semble propre.


Questions connexes:

John D. Cook
la source
Pendant un certain temps, les gens semblent trouver ma réponse NLTK (assez récente) extrêmement utile, vous voudrez peut-être envisager de changer la réponse acceptée. Merci!
Shatu
1
Je n'aurais jamais pensé tomber sur une question posée par l'auteur de mon blog préféré! The Endeavour!
Ryan G
1
@Shatu Maintenant que votre solution n'est plus valide, vous pouvez supprimer votre commentaire. Merci! ;)
Sнаđошƒаӽ

Réponses:

136

html2text est un programme Python qui fait un très bon travail dans ce domaine.

RexE
la source
5
bit c'est gpl 3.0 ce qui signifie qu'il peut être incompatible
frog32
138
Incroyable! son auteur est RIP Aaron Swartz.
Atul Arvind
2
Quelqu'un at-il trouvé des alternatives à html2text à cause de la GPL 3.0?
jontsai
1
La GPL n'est pas aussi mauvaise que les gens le souhaitent. Aaron savait le mieux.
Steve K
2
J'ai essayé à la fois html2text et nltk mais ils n'ont pas fonctionné pour moi. J'ai fini par aller avec Beautiful Soup 4, qui fonctionne à merveille (sans jeu de mots).
Ryan
150

Le meilleur morceau de code que j'ai trouvé pour extraire du texte sans obtenir du javascript ou des choses non désirées:

import urllib
from bs4 import BeautifulSoup

url = "http://news.bbc.co.uk/2/hi/health/2284783.stm"
html = urllib.urlopen(url).read()
soup = BeautifulSoup(html)

# kill all script and style elements
for script in soup(["script", "style"]):
    script.extract()    # rip it out

# get text
text = soup.get_text()

# break into lines and remove leading and trailing space on each
lines = (line.strip() for line in text.splitlines())
# break multi-headlines into a line each
chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
# drop blank lines
text = '\n'.join(chunk for chunk in chunks if chunk)

print(text)

Il vous suffit d'installer BeautifulSoup avant:

pip install beautifulsoup4
PeYoTlL
la source
2
Comment faire si nous voulons sélectionner une ligne, vient de dire, la ligne # 3?
hepidad
3
Le peu de tuer des scripts, sauveur !!
Nanda
2
Après avoir parcouru beaucoup de réponses stackoverflow, j'ai l'impression que c'est la meilleure option pour moi. Un problème que j'ai rencontré est que les lignes ont été additionnées dans certains cas. J'ai pu le surmonter en ajoutant un séparateur dans la fonction get_text:text = soup.get_text(separator=' ')
Joswin KJ
5
Au lieu de soup.get_text()j'ai utilisé soup.body.get_text(), de sorte que je n'obtienne aucun texte de l' <headélément>, comme le titre.
Sjoerd
10
Pour Python 3,from urllib.request import urlopen
Jacob Kalakal Joseph
99

REMARQUE: NTLK ne prend plus en charge la clean_htmlfonction

Réponse originale ci-dessous, et une alternative dans les sections commentaires.


Utiliser NLTK

J'ai perdu mes 4-5 heures à résoudre les problèmes avec html2text. Heureusement, j'ai pu rencontrer NLTK.
Cela fonctionne comme par magie.

import nltk   
from urllib import urlopen

url = "http://news.bbc.co.uk/2/hi/health/2284783.stm"    
html = urlopen(url).read()    
raw = nltk.clean_html(html)  
print(raw)
Shatu
la source
8
parfois cela suffit :)
Sharmila
8
Je veux voter mille fois. J'étais coincé dans l'enfer regex, mais voilà, maintenant je vois la sagesse de NLTK.
BenDundee
26
Apparemment, clean_html n'est plus supporté: github.com/nltk/nltk/commit/…
alexanderlukanin13
5
importer une bibliothèque lourde comme nltk pour une tâche aussi simple serait trop
richie
54
@ alexanderlukanin13 De la source:raise NotImplementedError ("To remove HTML markup, use BeautifulSoup's get_text() function")
Chris Arena
54

Je me suis retrouvé face au même problème aujourd'hui. J'ai écrit un analyseur HTML très simple pour supprimer le contenu entrant de tous les annotations, renvoyant le texte restant avec un minimum de mise en forme.

from HTMLParser import HTMLParser
from re import sub
from sys import stderr
from traceback import print_exc

class _DeHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.__text = []

    def handle_data(self, data):
        text = data.strip()
        if len(text) > 0:
            text = sub('[ \t\r\n]+', ' ', text)
            self.__text.append(text + ' ')

    def handle_starttag(self, tag, attrs):
        if tag == 'p':
            self.__text.append('\n\n')
        elif tag == 'br':
            self.__text.append('\n')

    def handle_startendtag(self, tag, attrs):
        if tag == 'br':
            self.__text.append('\n\n')

    def text(self):
        return ''.join(self.__text).strip()


def dehtml(text):
    try:
        parser = _DeHTMLParser()
        parser.feed(text)
        parser.close()
        return parser.text()
    except:
        print_exc(file=stderr)
        return text


def main():
    text = r'''
        <html>
            <body>
                <b>Project:</b> DeHTML<br>
                <b>Description</b>:<br>
                This small script is intended to allow conversion from HTML markup to 
                plain text.
            </body>
        </html>
    '''
    print(dehtml(text))


if __name__ == '__main__':
    main()
xperroni
la source
5
Cela semble être le moyen le plus simple de le faire en Python (2.7) en utilisant uniquement les modules par défaut. Ce qui est vraiment stupide, car c'est une chose si courante et il n'y a aucune bonne raison pour laquelle il n'y a pas d'analyseur pour cela dans le module HTMLParser par défaut.
Ingmar Hupp
2
Je ne pense pas que convertira les caractères html en unicode, non? Par exemple, &amp;ne sera pas converti en &, non?
speedplane
Pour Python 3, utilisezfrom html.parser import HTMLParser
sebhaase
14

Voici une version de la réponse de xperroni qui est un peu plus complète. Il ignore les sections de script et de style et traduit les caractères (par exemple, & # 39;) et les entités HTML (par exemple, & amp;).

Il comprend également un convertisseur inverse trivial de texte brut en html.

"""
HTML <-> text conversions.
"""
from HTMLParser import HTMLParser, HTMLParseError
from htmlentitydefs import name2codepoint
import re

class _HTMLToText(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self._buf = []
        self.hide_output = False

    def handle_starttag(self, tag, attrs):
        if tag in ('p', 'br') and not self.hide_output:
            self._buf.append('\n')
        elif tag in ('script', 'style'):
            self.hide_output = True

    def handle_startendtag(self, tag, attrs):
        if tag == 'br':
            self._buf.append('\n')

    def handle_endtag(self, tag):
        if tag == 'p':
            self._buf.append('\n')
        elif tag in ('script', 'style'):
            self.hide_output = False

    def handle_data(self, text):
        if text and not self.hide_output:
            self._buf.append(re.sub(r'\s+', ' ', text))

    def handle_entityref(self, name):
        if name in name2codepoint and not self.hide_output:
            c = unichr(name2codepoint[name])
            self._buf.append(c)

    def handle_charref(self, name):
        if not self.hide_output:
            n = int(name[1:], 16) if name.startswith('x') else int(name)
            self._buf.append(unichr(n))

    def get_text(self):
        return re.sub(r' +', ' ', ''.join(self._buf))

def html_to_text(html):
    """
    Given a piece of HTML, return the plain text it contains.
    This handles entities and char refs, but not javascript and stylesheets.
    """
    parser = _HTMLToText()
    try:
        parser.feed(html)
        parser.close()
    except HTMLParseError:
        pass
    return parser.get_text()

def text_to_html(text):
    """
    Convert the given text to html, wrapping what looks like URLs with <a> tags,
    converting newlines to <br> tags and converting confusing chars into html
    entities.
    """
    def f(mo):
        t = mo.group()
        if len(t) == 1:
            return {'&':'&amp;', "'":'&#39;', '"':'&quot;', '<':'&lt;', '>':'&gt;'}.get(t)
        return '<a href="%s">%s</a>' % (t, t)
    return re.sub(r'https?://[^] ()"\';]+|[&\'"<>]', f, text)
bit4
la source
Dans get_text, '' .join devrait être '' .join. Il devrait y avoir un espace vide, sinon certains textes se rejoindront.
Obinna Nnenanya
1
En outre, cela n'attrapera pas TOUS les textes, sauf que vous incluez d'autres balises de conteneur de texte comme H1, H2 ...., span, etc. J'ai dû l'ajuster pour une meilleure couverture.
Obinna Nnenanya
11

Je sais qu'il y a déjà beaucoup de réponses, mais la solution la plus élégante et pythonique que j'ai trouvée est décrite en partie ici .

from bs4 import BeautifulSoup

text = ''.join(BeautifulSoup(some_html_string, "html.parser").findAll(text=True))

Mettre à jour

Sur la base du commentaire de Fraser, voici une solution plus élégante:

from bs4 import BeautifulSoup

clean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings)
Floyd
la source
2
Pour éviter un avertissement, spécifiez un analyseur pour BeautifulSoup à utiliser:text = ''.join(BeautifulSoup(some_html_string, "lxml").findAll(text=True))
Floyd
Vous pouvez utiliser le générateur stripped_strings pour éviter les espaces blancs excessifs - par exempleclean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings
Fraser
8

Vous pouvez également utiliser la méthode html2text dans la bibliothèque de stripogrammes.

from stripogram import html2text
text = html2text(your_html_string)

Pour installer le stripogramme, exécutez sudo easy_install stripogram

GeekTantra
la source
23
Ce module, selon sa page pypi , est obsolète: "A moins que vous n'ayez une raison historique d'utiliser ce paquet, je vous déconseille!"
intuition
7

Il existe une bibliothèque de modèles pour l'exploration de données.

http://www.clips.ua.ac.be/pages/pattern-web

Vous pouvez même décider quelles balises conserver:

s = URL('http://www.clips.ua.ac.be').download()
s = plaintext(s, keep={'h1':[], 'h2':[], 'strong':[], 'a':['href']})
print s
Nuncjo
la source
6

PyParsing fait un excellent travail. Le wiki PyParsing a été tué alors voici un autre endroit où il y a des exemples d'utilisation de PyParsing ( exemple de lien ). Une des raisons pour investir un peu de temps dans le pyparsing est qu'il a également écrit un très bref manuel O'Reilly Short Cut très bien organisé qui est également peu coûteux.

Cela dit, j'utilise beaucoup BeautifulSoup et ce n'est pas si difficile de traiter les problèmes d'entités, vous pouvez les convertir avant d'exécuter BeautifulSoup.

Bonne chance

PyNEwbie
la source
1
Le lien est mort ou aigri.
Yvette
4

Ce n'est pas exactement une solution Python, mais cela convertira le texte que Javascript générerait en texte, ce qui, je pense, est important (EG google.com). Le navigateur Links (pas Lynx) a un moteur Javascript et convertira la source en texte avec l'option -dump.

Vous pourriez donc faire quelque chose comme:

fname = os.tmpnam()
fname.write(html_source)
proc = subprocess.Popen(['links', '-dump', fname], 
                        stdout=subprocess.PIPE,
                        stderr=open('/dev/null','w'))
text = proc.stdout.read()
Andrew
la source
4

Au lieu du module HTMLParser, consultez htmllib. Il a une interface similaire, mais fait plus de travail pour vous. (C'est assez ancien, donc ce n'est pas très utile pour se débarrasser de javascript et css. Vous pouvez créer une classe dérivée, mais et ajouter des méthodes avec des noms comme start_script et end_style (voir les documents python pour plus de détails), mais c'est difficile pour le faire de manière fiable pour le html malformé.) Quoi qu'il en soit, voici quelque chose de simple qui imprime le texte brut sur la console

from htmllib import HTMLParser, HTMLParseError
from formatter import AbstractFormatter, DumbWriter
p = HTMLParser(AbstractFormatter(DumbWriter()))
try: p.feed('hello<br>there'); p.close() #calling close is not usually needed, but let's play it safe
except HTMLParseError: print ':(' #the html is badly malformed (or you found a bug)
marque
la source
NB: HTMLError et HTMLParserError doivent tous deux lire HTMLParseError. Cela fonctionne, mais fait un mauvais travail de maintien des sauts de ligne.
Dave Knight
4

Je recommande un package Python appelé goose-extractor Goose essaiera d'extraire les informations suivantes:

Texte principal d'un article Image principale de l'article Tous les films Youtube / Vimeo intégrés à l'article Meta Description Meta tags

Plus: https://pypi.python.org/pypi/goose-extractor/

Li Yingjun
la source
4

si vous avez besoin de plus de vitesse et moins de précision, vous pouvez utiliser du lxml brut.

import lxml.html as lh
from lxml.html.clean import clean_html

def lxml_to_text(html):
    doc = lh.fromstring(html)
    doc = clean_html(doc)
    return doc.text_content()
Anton Shelin
la source
4

installer html2text en utilisant

installer pip html2text

puis,

>>> import html2text
>>>
>>> h = html2text.HTML2Text()
>>> # Ignore converting links from HTML
>>> h.ignore_links = True
>>> print h.handle("<p>Hello, <a href='http://earth.google.com/'>world</a>!")
Hello, world!
Pravitha V
la source
4

Je sais qu'il y a déjà beaucoup de réponses ici, mais je pense que journal3k mérite également une mention. J'ai récemment dû effectuer une tâche similaire d'extraction du texte d'articles sur le Web et cette bibliothèque a fait un excellent travail jusqu'à présent dans mes tests. Il ignore le texte trouvé dans les éléments de menu et les barres latérales ainsi que tout JavaScript qui apparaît sur la page à la demande du PO.

from newspaper import Article

article = Article(url)
article.download()
article.parse()
article.text

Si vous avez déjà téléchargé les fichiers HTML, vous pouvez faire quelque chose comme ceci:

article = Article('')
article.set_html(html)
article.parse()
article.text

Il a même quelques fonctionnalités NLP pour résumer les sujets des articles:

article.nlp()
article.summary
spatel4140
la source
3

Une belle soupe convertit les entités html. C'est probablement votre meilleur choix étant donné que le HTML est souvent bogué et rempli de problèmes d'encodage unicode et html. Voici le code que j'utilise pour convertir du HTML en texte brut:

import BeautifulSoup
def getsoup(data, to_unicode=False):
    data = data.replace("&nbsp;", " ")
    # Fixes for bad markup I've seen in the wild.  Remove if not applicable.
    masssage_bad_comments = [
        (re.compile('<!-([^-])'), lambda match: '<!--' + match.group(1)),
        (re.compile('<!WWWAnswer T[=\w\d\s]*>'), lambda match: '<!--' + match.group(0) + '-->'),
    ]
    myNewMassage = copy.copy(BeautifulSoup.BeautifulSoup.MARKUP_MASSAGE)
    myNewMassage.extend(masssage_bad_comments)
    return BeautifulSoup.BeautifulSoup(data, markupMassage=myNewMassage,
        convertEntities=BeautifulSoup.BeautifulSoup.ALL_ENTITIES 
                    if to_unicode else None)

remove_html = lambda c: getsoup(c, to_unicode=True).getText(separator=u' ') if c else ""
speedplane
la source
3

Une autre option consiste à exécuter le code HTML via un navigateur Web basé sur du texte et à le vider. Par exemple (en utilisant Lynx):

lynx -dump html_to_convert.html > converted_html.txt

Cela peut être fait dans un script python comme suit:

import subprocess

with open('converted_html.txt', 'w') as outputFile:
    subprocess.call(['lynx', '-dump', 'html_to_convert.html'], stdout=testFile)

Il ne vous donnera pas exactement le texte du fichier HTML, mais selon votre cas d'utilisation, il peut être préférable à la sortie de html2text.

John Lucas
la source
3

Le mieux a fonctionné pour moi, ce sont les scripts.

https://github.com/weblyzard/inscriptis

import urllib.request
from inscriptis import get_text

url = "http://www.informationscience.ch"
html = urllib.request.urlopen(url).read().decode('utf-8')

text = get_text(html)
print(text)

Les résultats sont vraiment bons

Vigueur
la source
2

Une autre solution non python: Libre Office:

soffice --headless --invisible --convert-to txt input1.html

La raison pour laquelle je préfère celle-ci aux autres alternatives est que chaque paragraphe HTML est converti en une seule ligne de texte (pas de saut de ligne), ce que je cherchais. D'autres méthodes nécessitent un post-traitement. Lynx produit une belle sortie, mais pas exactement ce que je cherchais. En outre, Libre Office peut être utilisé pour convertir à partir de toutes sortes de formats ...

YakovK
la source
2

Quelqu'un a essayé l' eaubleach.clean(html,tags=[],strip=True) de Javel ? ça marche pour moi.

rox
la source
Semble fonctionner pour moi aussi, mais ils ne recommandent pas de l'utiliser à cette fin: "Cette fonction est une fonction axée sur la sécurité dont le seul but est de supprimer le contenu malveillant d'une chaîne de sorte qu'il puisse être affiché comme contenu dans un site Web page." -> bleach.readthedocs.io/en/latest/clean.html#bleach.clean
Loktopus
2

J'ai eu de bons résultats avec Apache Tika . Son but est l'extraction des métadonnées et du texte du contenu, d'où l'analyseur sous-jacent est réglé en conséquence hors de la boîte.

Tika peut être exécuté en tant que serveur , est facile à exécuter / déployer dans un conteneur Docker, et à partir de là, il est accessible via des liaisons Python .

u-phoria
la source
1

d'une manière simple

import re

html_text = open('html_file.html').read()
text_filtered = re.sub(r'<(.*?)>', '', html_text)

ce code trouve toutes les parties du html_text commencées par «<» et se terminant par «>» et remplace toutes celles trouvées par une chaîne vide

David Fraga
la source
1

@ La réponse de PeYoTIL en utilisant BeautifulSoup et en éliminant le style et le contenu du script n'a pas fonctionné pour moi. Je l'ai essayé en utilisant decomposeau lieu de extractmais cela n'a toujours pas fonctionné. J'ai donc créé le mien qui formate également le texte à l'aide des <p>balises et remplace les <a>balises par le lien href. Gère également les liens à l'intérieur du texte. Disponible à ce point avec un doc de test intégré.

from bs4 import BeautifulSoup, NavigableString

def html_to_text(html):
    "Creates a formatted text email message as a string from a rendered html template (page)"
    soup = BeautifulSoup(html, 'html.parser')
    # Ignore anything in head
    body, text = soup.body, []
    for element in body.descendants:
        # We use type and not isinstance since comments, cdata, etc are subclasses that we don't want
        if type(element) == NavigableString:
            # We use the assumption that other tags can't be inside a script or style
            if element.parent.name in ('script', 'style'):
                continue

            # remove any multiple and leading/trailing whitespace
            string = ' '.join(element.string.split())
            if string:
                if element.parent.name == 'a':
                    a_tag = element.parent
                    # replace link text with the link
                    string = a_tag['href']
                    # concatenate with any non-empty immediately previous string
                    if (    type(a_tag.previous_sibling) == NavigableString and
                            a_tag.previous_sibling.string.strip() ):
                        text[-1] = text[-1] + ' ' + string
                        continue
                elif element.previous_sibling and element.previous_sibling.name == 'a':
                    text[-1] = text[-1] + ' ' + string
                    continue
                elif element.parent.name == 'p':
                    # Add extra paragraph formatting newline
                    string = '\n' + string
                text += [string]
    doc = '\n'.join(text)
    return doc
racitup
la source
1
Merci, cette réponse est sous-estimée. Pour ceux d'entre nous qui veulent avoir une représentation de texte propre qui se comporte plus comme un navigateur (en ignorant les nouvelles lignes et en ne prenant en compte que les paragraphes et les sauts de ligne), BeautifulSoup get_textne le coupe tout simplement pas.
jrial le
@jrial heureux que vous l'ayez trouvé utile, merci également pour la contribution. Pour n'importe qui d'autre, l'essentiel lié a été amélioré un peu. L'OP semble faire allusion à un outil qui rend le HTML en texte, un peu comme un navigateur basé sur du texte comme Lynx. C'est ce que tente cette solution. Ce que la plupart des gens contribuent sont simplement des extracteurs de texte.
racitup
1

Dans Python 3.x, vous pouvez le faire d'une manière très simple en important des packages 'imaplib' et 'email'. Bien que ce soit un post plus ancien, mais ma réponse peut peut-être aider les nouveaux arrivants sur ce post.

status, data = self.imap.fetch(num, '(RFC822)')
email_msg = email.message_from_bytes(data[0][1]) 
#email.message_from_string(data[0][1])

#If message is multi part we only want the text version of the body, this walks the message and gets the body.

if email_msg.is_multipart():
    for part in email_msg.walk():       
        if part.get_content_type() == "text/plain":
            body = part.get_payload(decode=True) #to control automatic email-style MIME decoding (e.g., Base64, uuencode, quoted-printable)
            body = body.decode()
        elif part.get_content_type() == "text/html":
            continue

Vous pouvez maintenant imprimer la variable de corps et elle sera au format texte brut :) Si cela vous convient, il serait bien de la sélectionner comme réponse acceptée.

Wahib Ul Haq
la source
Cela ne convertit rien.
Antti Haapala du
1
Cela vous montre comment extraire une text/plainpartie d'un e-mail si quelqu'un d'autre en a mis une. Il ne fait rien pour convertir le HTML en texte brut et ne fait rien d'utile à distance si vous essayez de convertir du HTML à partir, disons, d'un site Web.
tripleee
1

vous ne pouvez extraire que du texte de HTML avec BeautifulSoup

url = "https://www.geeksforgeeks.org/extracting-email-addresses-using-regular-expressions-python/"
con = urlopen(url).read()
soup = BeautifulSoup(con,'html.parser')
texts = soup.get_text()
print(texts)
Sai Gopi N
la source
1

Bien que de nombreuses personnes aient mentionné l'utilisation de l'expression rationnelle pour supprimer les balises HTML, il existe de nombreux inconvénients.

par exemple:

<p>hello&nbsp;world</p>I love you

Doit être analysé pour:

Hello world
I love you

Voici un extrait que j'ai trouvé, vous pouvez le personnaliser selon vos besoins spécifiques, et cela fonctionne comme un charme

import re
import html
def html2text(htm):
    ret = html.unescape(htm)
    ret = ret.translate({
        8209: ord('-'),
        8220: ord('"'),
        8221: ord('"'),
        160: ord(' '),
    })
    ret = re.sub(r"\s", " ", ret, flags = re.MULTILINE)
    ret = re.sub("<br>|<br />|</p>|</div>|</h\d>", "\n", ret, flags = re.IGNORECASE)
    ret = re.sub('<.*?>', ' ', ret, flags=re.DOTALL)
    ret = re.sub(r"  +", " ", ret)
    return ret
Uri Goren
la source
1

Un autre exemple utilisant BeautifulSoup4 dans Python 2.7.9+

comprend:

import urllib2
from bs4 import BeautifulSoup

Code:

def read_website_to_text(url):
    page = urllib2.urlopen(url)
    soup = BeautifulSoup(page, 'html.parser')
    for script in soup(["script", "style"]):
        script.extract() 
    text = soup.get_text()
    lines = (line.strip() for line in text.splitlines())
    chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
    text = '\n'.join(chunk for chunk in chunks if chunk)
    return str(text.encode('utf-8'))

Expliqué:

Lisez les données url en html (en utilisant BeautifulSoup), supprimez tous les éléments de script et de style, et obtenez également le texte en utilisant .get_text (). Séparez en lignes et supprimez les espaces de début et de fin sur chacun, puis divisez les titres multiples en une ligne chaque morceau = (phrase.strip () pour la ligne en lignes pour la phrase en ligne.split ("")). Ensuite, en utilisant text = '\ n'.join, supprimez les lignes vierges, puis retournez comme sanctionné utf-8.

Remarques:

  • Certains systèmes sur lesquels cela s'exécute échoueront avec les connexions https: // en raison d'un problème SSL, vous pouvez désactiver la vérification pour résoudre ce problème. Exemple de correctif: http://blog.pengyifan.com/how-to-fix-python-ssl-certificate_verify_failed/

  • Python <2.7.9 peut rencontrer des problèmes lors de l'exécution de ce

  • text.encode ('utf-8') peut laisser un encodage étrange, peut vouloir simplement renvoyer str (text) à la place.

Mike Q
la source
0

Voici le code que j'utilise régulièrement.

from bs4 import BeautifulSoup
import urllib.request


def processText(webpage):

    # EMPTY LIST TO STORE PROCESSED TEXT
    proc_text = []

    try:
        news_open = urllib.request.urlopen(webpage.group())
        news_soup = BeautifulSoup(news_open, "lxml")
        news_para = news_soup.find_all("p", text = True)

        for item in news_para:
            # SPLIT WORDS, JOIN WORDS TO REMOVE EXTRA SPACES
            para_text = (' ').join((item.text).split())

            # COMBINE LINES/PARAGRAPHS INTO A LIST
            proc_text.append(para_text)

    except urllib.error.HTTPError:
        pass

    return proc_text

J'espère que ça aide.

troymyname00
la source
0

Le commentaire de l'écrivain LibreOffice a du mérite puisque l'application peut utiliser des macros python. Il semble offrir de multiples avantages à la fois pour répondre à cette question et pour développer la base macro de LibreOffice. Si cette résolution est une implémentation unique, plutôt que d'être utilisée dans le cadre d'un programme de production plus important, l'ouverture du code HTML dans le rédacteur et l'enregistrement de la page en tant que texte semblent résoudre les problèmes abordés ici.

1de7
la source
0

Perl way (désolé maman, je ne le ferai jamais en production).

import re

def html2text(html):
    res = re.sub('<.*?>', ' ', html, flags=re.DOTALL | re.MULTILINE)
    res = re.sub('\n+', '\n', res)
    res = re.sub('\r+', '', res)
    res = re.sub('[\t ]+', ' ', res)
    res = re.sub('\t+', '\t', res)
    res = re.sub('(\n )+', '\n ', res)
    return res
brunql
la source
C'est une mauvaise pratique pour tant de raisons, par exemple&nbsp;
Uri Goren
Oui! C'est vrai! Ne le faites pas là-bas!
brunql