Extrahieren von Text aus einer HTML-Datei mit Python

243

Ich möchte den Text mit Python aus einer HTML-Datei extrahieren. Ich möchte im Wesentlichen die gleiche Ausgabe, die ich erhalten würde, wenn ich den Text aus einem Browser kopieren und in den Editor einfügen würde.

Ich hätte gerne etwas Robusteres als die Verwendung regulärer Ausdrücke, die bei schlecht geformtem HTML fehlschlagen könnten. Ich habe viele Leute gesehen, die Beautiful Soup empfohlen haben, aber ich hatte ein paar Probleme damit. Zum einen wurden unerwünschte Texte wie JavaScript-Quellen erfasst. Außerdem wurden HTML-Entitäten nicht interpretiert. Zum Beispiel würde ich erwarten, & # 39; in einer HTML-Quelle, die im Text in ein Apostroph konvertiert werden soll, als hätte ich den Browserinhalt in den Editor eingefügt.

Update html2text sieht vielversprechend aus. Es behandelt HTML-Entitäten korrekt und ignoriert JavaScript. Es wird jedoch nicht genau Klartext erzeugt. es erzeugt einen Abschlag, der dann in einfachen Text umgewandelt werden müsste. Es enthält keine Beispiele oder Dokumentation, aber der Code sieht sauber aus.


Verwandte Fragen:

John D. Cook
quelle
Seit einiger Zeit scheinen die Leute meine NLTK-Antwort (ziemlich neu) als äußerst nützlich zu empfinden. Vielleicht möchten Sie die akzeptierte Antwort ändern. Vielen Dank!
Shatu
1
Ich hätte nie gedacht, dass ich auf eine Frage des Autors meines Lieblingsblogs stoßen würde! Das Bestreben!
Ryan G
1
@Shatu Nachdem Ihre Lösung nicht mehr gültig ist, möchten Sie möglicherweise Ihren Kommentar löschen. Vielen Dank! ;)
Sнаđошƒаӽ

Antworten:

136

html2text ist ein Python-Programm, das hier ziemlich gute Arbeit leistet.

RexE
quelle
5
Bit es ist gpl 3.0, was bedeutet, dass es möglicherweise nicht kompatibel ist
frog32
138
Tolle! Der Autor ist RIP Aaron Swartz.
Atul Arvind
2
Hat jemand aufgrund von GPL 3.0 Alternativen zu html2text gefunden?
Jontsai
1
GPL nicht so schlecht, wie die Leute es wollen. Aaron wusste es am besten.
Steve K
2
Ich habe sowohl html2text als auch nltk ausprobiert, aber sie haben bei mir nicht funktioniert. Am Ende habe ich mich für Beautiful Soup 4 entschieden, das wunderbar funktioniert (kein Wortspiel beabsichtigt).
Ryan
149

Der beste Code, den ich zum Extrahieren von Text gefunden habe, ohne Javascript zu erhalten oder Dinge nicht zu wollen:

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)

Sie müssen BeautifulSoup nur installieren, bevor Sie:

pip install beautifulsoup4
PeYoTlL
quelle
2
Wie wäre es, wenn wir eine Zeile auswählen möchten, gerade gesagt, Zeile 3?
Hepidad
3
Die Tötungsskripte haben gebissen, Retter !!
Nanda
2
Nachdem ich viele Stackoverflow-Antworten durchgearbeitet habe, denke ich, dass dies die beste Option für mich ist. Ein Problem, auf das ich gestoßen bin, ist, dass in einigen Fällen Zeilen addiert wurden. Ich konnte es überwinden, indem ich ein Trennzeichen in die Funktion get_text einfügte:text = soup.get_text(separator=' ')
Joswin KJ
5
Anstelle von soup.get_text()Ich habe verwendet soup.body.get_text(), damit ich keinen Text vom <head> Element erhalte , wie z. B. den Titel.
Sjoerd
10
Für Python 3from urllib.request import urlopen
Jacob Kalakal Joseph
99

HINWEIS : NTLK unterstützt die clean_htmlFunktion nicht mehr

Originalantwort unten und eine Alternative in den Kommentaren.


Verwenden Sie NLTK

Ich habe meine 4-5 Stunden damit verbracht, die Probleme mit html2text zu beheben. Zum Glück konnte ich NLTK begegnen.
Es funktioniert magisch.

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
quelle
8
manchmal ist das genug :)
Sharmila
8
Ich möchte dies tausendmal abstimmen. Ich war in der Regex-Hölle gefangen, aber siehe da, jetzt sehe ich die Weisheit von NLTK.
BenDundee
26
Anscheinend wird clean_html nicht mehr unterstützt: github.com/nltk/nltk/commit/…
alexanderlukanin13
5
Eine schwere Bibliothek wie nltk für eine so einfache Aufgabe zu importieren wäre zu viel
richie
54
@ Alexanderlukanin13 Aus der Quelle:raise NotImplementedError ("To remove HTML markup, use BeautifulSoup's get_text() function")
Chris Arena
54

Ich stand heute vor dem gleichen Problem. Ich habe einen sehr einfachen HTML-Parser geschrieben, um eingehenden Inhalt aller Markups zu entfernen und den verbleibenden Text mit nur einem Minimum an Formatierung zurückzugeben.

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
quelle
5
Dies scheint die einfachste Möglichkeit zu sein, dies in Python (2.7) nur mit den Standardmodulen zu tun. Was wirklich albern ist, da dies so häufig benötigt wird und es keinen guten Grund gibt, warum es im Standard-HTMLParser-Modul keinen Parser dafür gibt.
Ingmar Hupp
2
Ich glaube nicht, dass HTML-Zeichen in Unicode konvertiert werden, oder? &amp;Wird zum Beispiel nicht konvertiert &, oder?
Speedplane
Für Python 3 verwenden Siefrom html.parser import HTMLParser
sebhaase
14

Hier ist eine Version von xperronis Antwort, die etwas vollständiger ist. Es überspringt Skript- und Stilabschnitte und übersetzt Zeichen (z. B. & # 39;) und HTML-Entitäten (z. B. & amp;).

Es enthält auch einen einfachen Umkehrkonverter von Klartext zu 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
quelle
In get_text sollte '' .join '' .join sein. Es sollte ein leerer Raum sein, sonst werden einige der Texte zusammengefügt.
Obinna Nnenanya
1
Außerdem werden dadurch nicht ALLE Texte erfasst, außer Sie fügen andere Textcontainer-Tags wie H1, H2 ...., span usw. hinzu. Ich musste sie für eine bessere Abdeckung optimieren.
Obinna Nnenanya
11

Ich weiß, dass es bereits viele Antworten gibt, aber die eleganteste und pythonischste Lösung, die ich gefunden habe, wird teilweise hier beschrieben .

from bs4 import BeautifulSoup

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

Aktualisieren

Basierend auf Frasers Kommentar ist hier eine elegantere Lösung:

from bs4 import BeautifulSoup

clean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings)
Floyd
quelle
2
Um eine Warnung zu vermeiden, geben Sie einen Parser für BeautifulSoup an:text = ''.join(BeautifulSoup(some_html_string, "lxml").findAll(text=True))
Floyd
Sie können den Generator stripped_strings verwenden, um übermäßigen Leerraum zu vermeiden - dhclean_text = ''.join(BeautifulSoup(some_html_string, "html.parser").stripped_strings
Fraser
8

Sie können die html2text-Methode auch in der Stripogram-Bibliothek verwenden.

from stripogram import html2text
text = html2text(your_html_string)

Um Stripogram zu installieren, führen Sie sudo easy_install stripogram aus

GeekTantra
quelle
23
Dieses Modul ist laut seiner Pypi-Seite veraltet: "Wenn Sie keinen historischen Grund für die Verwendung dieses Pakets haben, würde ich davon abraten!"
Intuiert
7

Es gibt eine Musterbibliothek für Data Mining.

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

Sie können sogar entscheiden, welche Tags beibehalten werden sollen:

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

PyParsing macht einen tollen Job. Das PyParsing-Wiki wurde getötet. Hier ist ein weiterer Ort, an dem es Beispiele für die Verwendung von PyParsing gibt ( Beispiellink ). Ein Grund, ein wenig Zeit mit Pyparsing zu verbringen, ist, dass er auch ein sehr kurzes, sehr gut organisiertes O'Reilly Short Cut-Handbuch geschrieben hat, das auch kostengünstig ist.

Trotzdem verwende ich BeautifulSoup häufig und es ist nicht so schwer, mit den Entitätsproblemen umzugehen. Sie können sie konvertieren, bevor Sie BeautifulSoup ausführen.

Viel Glück

PyNEwbie
quelle
1
Der Link ist tot oder sauer.
Yvette
4

Dies ist nicht gerade eine Python-Lösung, aber sie konvertiert Text, den Javascript in Text generieren würde, was ich für wichtig halte (z. B. google.com). Die Browser-Links (nicht Lynx) verfügen über eine Javascript-Engine und konvertieren die Quelle mit der Option -dump in Text.

Sie könnten also so etwas tun:

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

Schauen Sie sich anstelle des HTMLParser-Moduls htmllib an. Es hat eine ähnliche Oberfläche, erledigt aber mehr Arbeit für Sie. (Es ist ziemlich alt, daher ist es keine große Hilfe, um Javascript und CSS loszuwerden. Sie könnten eine abgeleitete Klasse erstellen, aber Methoden mit Namen wie start_script und end_style hinzufügen (Details finden Sie in den Python-Dokumenten), aber es ist schwierig um dies zuverlässig für fehlerhaftes HTML zu tun.) Wie auch immer, hier ist etwas Einfaches, das den Klartext auf die Konsole druckt

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)
Kennzeichen
quelle
NB: HTMLError und HTMLParserError sollten beide HTMLParseError lesen. Dies funktioniert, macht aber einen schlechten Job bei der Aufrechterhaltung von Zeilenumbrüchen.
Dave Knight
4

Ich empfehle ein Python-Paket namens Goose-Extractor Goose, das versucht, die folgenden Informationen zu extrahieren:

Haupttext eines Artikels Hauptbild des Artikels Alle in Artikel eingebetteten Youtube / Vimeo-Filme Meta Beschreibung Meta-Tags

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

Li Yingjun
quelle
4

Wenn Sie mehr Geschwindigkeit und weniger Genauigkeit benötigen, können Sie rohes lxml verwenden.

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

Installieren Sie html2text mit

pip install html2text

dann,

>>> 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.
quelle
4

Ich weiß, dass es hier bereits viele Antworten gibt, aber ich denke, zeitung3k verdient auch eine Erwähnung. Ich musste kürzlich eine ähnliche Aufgabe erledigen, um den Text aus Artikeln im Web zu extrahieren, und diese Bibliothek hat dies in meinen Tests bisher hervorragend erreicht. Es ignoriert den Text in Menüelementen und Seitenleisten sowie jegliches JavaScript, das auf der Seite als OP-Anforderung angezeigt wird.

from newspaper import Article

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

Wenn Sie die HTML-Dateien bereits heruntergeladen haben, können Sie Folgendes tun:

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

Es gibt sogar einige NLP-Funktionen zum Zusammenfassen der Themen von Artikeln:

article.nlp()
article.summary
Spatel4140
quelle
3

Schöne Suppe konvertiert HTML-Entitäten. Dies ist wahrscheinlich die beste Wahl, wenn man bedenkt, dass HTML häufig fehlerhaft ist und Probleme mit der Unicode- und HTML-Codierung aufweist. Dies ist der Code, mit dem ich HTML in Rohtext konvertiere:

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 ""
Geschwindigkeitsflugzeug
quelle
3

Eine andere Möglichkeit besteht darin, den HTML-Code über einen textbasierten Webbrowser auszuführen und zu sichern. Zum Beispiel (mit Lynx):

lynx -dump html_to_convert.html > converted_html.txt

Dies kann in einem Python-Skript wie folgt erfolgen:

import subprocess

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

Sie erhalten nicht genau den Text aus der HTML-Datei, aber je nach Anwendungsfall ist er möglicherweise der Ausgabe von html2text vorzuziehen.

John Lucas
quelle
3

Am besten funktioniert für mich Inschriften.

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)

Die Ergebnisse sind wirklich gut

Vim
quelle
2

Eine andere Nicht-Python-Lösung: Libre Office:

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

Der Grund, warum ich diesen anderen Alternativen vorziehe, ist, dass jeder HTML-Absatz in eine einzelne Textzeile konvertiert wird (keine Zeilenumbrüche), wonach ich gesucht habe. Andere Methoden erfordern eine Nachbearbeitung. Lynx liefert zwar eine gute Ausgabe, aber nicht genau das, wonach ich gesucht habe. Außerdem kann Libre Office verwendet werden, um aus allen möglichen Formaten zu konvertieren ...

YakovK
quelle
2

Hat jemand bleach.clean(html,tags=[],strip=True)mit Bleichmittel versucht ? es funktioniert für mich.

rox
quelle
Scheint auch für mich zu funktionieren, aber sie empfehlen nicht, es für diesen Zweck zu verwenden: "Diese Funktion ist eine sicherheitsorientierte Funktion, deren einziger Zweck darin besteht, schädlichen Inhalt aus einer Zeichenfolge zu entfernen, damit er als Inhalt in einem Web angezeigt werden kann Seite." -> bleach.readthedocs.io/en/latest/clean.html#bleach.clean
Loktopus
2

Ich habe mit Apache Tika gute Ergebnisse erzielt . Sein Zweck ist das Extrahieren von Metadaten und Text aus Inhalten, daher wird der zugrunde liegende Parser sofort entsprechend optimiert.

Tika kann als Server ausgeführt werden , ist in einem Docker-Container trivial auszuführen und bereitzustellen und kann von dort über Python-Bindungen aufgerufen werden .

U-Phoria
quelle
1

auf einfache Weise

import re

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

Dieser Code findet alle Teile des HTML-Textes, die mit '<' beginnen und mit '>' enden, und ersetzt alle gefundenen durch eine leere Zeichenfolge

David Fraga
quelle
1

Die Antwort von @ PeYoTIL mit BeautifulSoup und das Eliminieren von Stil- und Skriptinhalten hat bei mir nicht funktioniert. Ich habe es mit decomposestatt versucht, extractaber es hat immer noch nicht funktioniert. Also habe ich meine eigene erstellt, die auch den Text mit den <p>Tags formatiert und <a>Tags durch den href-Link ersetzt. Bewältigt auch Links im Text. Verfügbar in diesem Kern mit einem eingebetteten Testdokument .

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
quelle
1
Danke, diese Antwort wird unterschätzt. Für diejenigen von uns, die eine saubere Textdarstellung wünschen, die sich eher wie ein Browser verhält (Zeilenumbrüche ignorieren und nur Absätze und Zeilenumbrüche berücksichtigen), get_textschneidet BeautifulSoup's einfach nicht ab.
jrial
@jrial froh, dass Sie es nützlich fanden, auch danke für den Beitrag. Für alle anderen wurde der Kern der Verknüpfung erheblich verbessert. Das OP scheint auf ein Tool hinzuweisen, das HTML in Text umwandelt, ähnlich wie ein textbasierter Browser wie lynx. Das versucht diese Lösung. Was die meisten Leute beitragen, sind nur Textextraktoren.
Racitup
1

In Python 3.x können Sie dies auf sehr einfache Weise tun, indem Sie die Pakete 'imaplib' und 'email' importieren. Dies ist zwar ein älterer Beitrag, aber vielleicht kann meine Antwort Neulingen in diesem Beitrag helfen.

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

Jetzt können Sie die Body-Variable drucken und sie wird im Klartext-Format vorliegen :) Wenn sie für Sie gut genug ist, wäre es schön, sie als akzeptierte Antwort auszuwählen.

Wahib Ul Haq
quelle
Dies konvertiert nichts.
Antti Haapala
1
Hier erfahren Sie, wie Sie ein text/plainTeil aus einer E-Mail extrahieren, wenn jemand anderes eines dort abgelegt hat. Es konvertiert den HTML-Code nicht in Klartext und ist auch nicht im entferntesten nützlich, wenn Sie versuchen, HTML-Code beispielsweise von einer Website zu konvertieren.
Tripleee
1

Mit BeautifulSoup können Sie nur Text aus HTML extrahieren

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.
quelle
1

Während viele Leute erwähnten, Regex zu verwenden, um HTML-Tags zu entfernen, gibt es viele Nachteile.

beispielsweise:

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

Sollte analysiert werden zu:

Hello world
I love you

Hier ist ein Ausschnitt, den ich mir ausgedacht habe. Sie können ihn an Ihre spezifischen Bedürfnisse anpassen und er funktioniert wie ein Zauber

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

Ein weiteres Beispiel für die Verwendung von BeautifulSoup4 in Python 2.7.9+

beinhaltet:

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

Erklärt:

Lesen Sie die URL-Daten als HTML ein (mit BeautifulSoup), entfernen Sie alle Skript- und Stilelemente und rufen Sie mit .get_text () nur den Text ab. Brechen Sie in Zeilen ein und entfernen Sie jeweils führende und nachfolgende Leerzeichen. Teilen Sie dann mehrere Überschriften in eine Zeile auf, die jeweils Chunks = (Phrase.strip () für Zeile in Zeilen für Phrase in Zeile.Split ("")). Verwenden Sie dann text = '\ n'.join, lassen Sie leere Zeilen fallen und kehren Sie schließlich als sanktioniertes utf-8 zurück.

Anmerkungen:

  • Einige Systeme, auf denen dies ausgeführt wird, schlagen aufgrund eines SSL-Problems mit https: // -Verbindungen fehl. Sie können die Überprüfung deaktivieren, um dieses Problem zu beheben. Beispielfix: http://blog.pengyifan.com/how-to-fix-python-ssl-certificate_verify_failed/

  • Python <2.7.9 hat möglicherweise ein Problem beim Ausführen

  • text.encode ('utf-8') kann eine seltsame Codierung hinterlassen und möchte stattdessen möglicherweise nur str (text) zurückgeben.

Mike Q.
quelle
0

Hier ist der Code, den ich regelmäßig verwende.

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

Ich hoffe das hilft.

troymyname00
quelle
0

Der LibreOffice-Writer-Kommentar ist sinnvoll, da die Anwendung Python-Makros verwenden kann. Es scheint mehrere Vorteile zu bieten, sowohl für die Beantwortung dieser Frage als auch für die Förderung der Makrobasis von LibreOffice. Wenn diese Lösung eine einmalige Implementierung ist und nicht als Teil eines größeren Produktionsprogramms verwendet werden soll, scheint das Öffnen des HTML-Codes im Writer und das Speichern der Seite als Text die hier diskutierten Probleme zu lösen.

1 von 7
quelle
0

Perl Weg (sorry Mama, ich werde es nie in der Produktion tun).

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
quelle
Dies ist aus so vielen Gründen eine schlechte Praxis, zum Beispiel&nbsp;
Uri Goren
Ja! Es ist wahr! Tu es nicht weiter!
Brunql