from mechanize import Browser
br = Browser()
br.open('http://somewebpage')
html = br.response().readlines()
for line in html:
print line
Beim Drucken einer Zeile in einer HTML-Datei versuche ich, nur den Inhalt jedes HTML-Elements und nicht die Formatierung selbst anzuzeigen. Wenn es findet '<a href="whatever.com">some text</a>'
, druckt es nur "Text", '<b>hello</b>'
"Hallo" usw. Wie würde man das machen?
&
. B. ). Sie können entweder 1) sie zusammen mit den Tags entfernen (oft unerwünscht und unnötig, da sie einfachem Text entsprechen), 2) sie unverändert lassen (eine geeignete Lösung, wenn der gestrippte Text direkt in einen HTML-Kontext zurückkehrt) oder 3) ) dekodieren Sie sie in einfachen Text (wenn der gestrippte Text in eine Datenbank oder einen anderen Nicht-HTML-Kontext verschoben wird oder wenn Ihr Webframework automatisch HTML-Escapezeichen für Sie ausführt).Antworten:
Ich habe diese Funktion immer verwendet, um HTML-Tags zu entfernen, da nur die Python-Stdlib erforderlich ist:
Für Python 3:
Für Python 2:
quelle
&
) als auch Tags entfernt werden.__init__
Funktion der übergeordneten Klasse aufrufen müssen. Siehe hier: stackoverflow.com/questions/11061058/… .parser = HTMLParser()
undhtml = parser.unescape(html)
am Anfang der Funktion strip_tags.Ich habe nicht viel über die Fälle nachgedacht, die es vermissen wird, aber Sie können einen einfachen regulären Ausdruck machen:
Für diejenigen, die Regex nicht verstehen, wird nach einer Zeichenfolge gesucht,
<...>
bei der der innere Inhalt aus einem oder mehreren (+
) Zeichen besteht, die kein a sind<
. Dies?
bedeutet, dass es mit der kleinsten Zeichenfolge übereinstimmt, die es finden kann. Zum Beispiel<p>Hello</p>
wird es übereinstimmen<'p>
und</p>
separat mit dem?
. Ohne sie wird es mit der gesamten Zeichenfolge übereinstimmen<..Hello..>
.Wenn
<
in HTML (z. B.2 < 3
) kein Tag angezeigt wird , sollte es&...
ohnehin als Escape-Sequenz geschrieben werden, damit dies^<
möglicherweise nicht erforderlich ist.quelle
&
) in der Ausgabe unverändert bleiben.cgi.escape(s, True)
), auch wenn Sie "wissen", dass sie kein HTML enthält (z. B. weil Sie HTML-Inhalte entfernt haben). . Dies ist jedoch nicht das, wonach OP gefragt hat.Sie können die BeautifulSoup-
get_text()
Funktion verwenden.Es ist ratsam, den Parser explizit anzugeben , z. B.
BeautifulSoup(html_str, features="html.parser")
damit die Ausgabe reproduzierbar ist.quelle
Kurzfassung!
Regex-Quelle: MarkupSafe . Ihre Version verarbeitet auch HTML-Entitäten, während diese schnelle dies nicht tut.
Warum kann ich die Tags nicht einfach entfernen und lassen?
Es ist eine Sache, Menschen von
<i>italicizing</i>
Dingen fernzuhalten , ohne dass siei
herumschweben. Aber es ist eine andere Sache, willkürliche Eingaben zu machen und sie völlig harmlos zu machen. Bei den meisten Techniken auf dieser Seite<!--
bleiben Dinge wie nicht geschlossene Kommentare ( ) und spitze Klammern, die nicht Teil von tags (blah <<<><blah
) sind, intakt. Die HTMLParser-Version kann sogar vollständige Tags hinterlassen, wenn sie sich in einem nicht geschlossenen Kommentar befinden.Was ist, wenn Ihre Vorlage ist
{{ firstname }} {{ lastname }}
?firstname = '<a'
undlastname = 'href="http://evil.com/">'
wird von jedem Tag-Stripper auf dieser Seite (außer @Medeiros!) durchgelassen, da es sich nicht um vollständige Tags handelt. Das Entfernen normaler HTML-Tags reicht nicht aus.Django's
strip_tags
, eine verbesserte (siehe nächste Überschrift) Version der Top-Antwort auf diese Frage, gibt die folgende Warnung:Folgen Sie ihrem Rat!
Um Tags mit HTMLParser zu entfernen, müssen Sie es mehrmals ausführen.
Es ist einfach, die beste Antwort auf diese Frage zu umgehen.
Schauen Sie sich diese Zeichenfolge an ( Quelle und Diskussion ):
Wenn HTMLParser es zum ersten Mal sieht, kann es nicht erkennen, dass
<img...>
es sich um ein Tag handelt. Es sieht kaputt aus, sodass HTMLParser es nicht loswird. Es nimmt nur das heraus<!-- comments -->
und lässt dich mitDieses Problem wurde dem Django-Projekt im März 2014 mitgeteilt. Ihr altes Problem entsprach im
strip_tags
Wesentlichen der Top-Antwort auf diese Frage. Ihre neue Version führt es im Grunde genommen in einer Schleife aus, bis das erneute Ausführen die Zeichenfolge nicht ändert:Natürlich ist nichts davon ein Problem, wenn Sie immer dem Ergebnis von entkommen
strip_tags()
.Update 19. März 2015 : In den Django-Versionen vor 1.4.20, 1.6.11, 1.7.7 und 1.8c1 ist ein Fehler aufgetreten. Diese Versionen könnten in der Funktion strip_tags () eine Endlosschleife eingeben. Die feste Version ist oben wiedergegeben. Weitere Details hier .
Gute Dinge zum Kopieren oder Verwenden
Mein Beispielcode verarbeitet keine HTML-Entitäten - die Paketversionen Django und MarkupSafe tun dies.
Mein Beispielcode stammt aus der hervorragenden MarkupSafe- Bibliothek zur Verhinderung von Cross-Site-Scripting. Es ist bequem und schnell (mit C-Beschleunigungen auf die native Python-Version). Es ist in der Google App Engine enthalten und wird von Jinja2 (2.7 und höher) , Mako, Pylons und anderen verwendet. Es funktioniert problemlos mit Django-Vorlagen aus Django 1.7.
Djangos strip_tags und andere HTML-Dienstprogramme aus einer neueren Version sind gut, aber ich finde sie weniger praktisch als MarkupSafe. Sie sind ziemlich eigenständig. Sie können aus dieser Datei kopieren, was Sie benötigen .
Wenn Sie fast alle Tags entfernen müssen, ist die Bleach- Bibliothek gut. Sie können Regeln wie "Meine Benutzer können Dinge kursiv schreiben, aber sie können keine Iframes erstellen" erzwingen lassen.
Verstehen Sie die Eigenschaften Ihres Tag Strippers! Führen Sie Fuzz-Tests durch! Hier ist der Code, mit dem ich nach dieser Antwort gesucht habe.
verlegener Hinweis - Bei der Frage selbst geht es um das Drucken auf der Konsole. Dies ist jedoch das beste Google-Ergebnis für "Python-Strip-HTML von Zeichenfolge". Aus diesem Grund bezieht sich diese Antwort zu 99% auf das Web.
quelle
Ich brauchte eine Möglichkeit, Tags zu entfernen und HTML-Entitäten in einfachen Text zu dekodieren. Die folgende Lösung basiert auf Eloffs Antwort (die ich nicht verwenden konnte, weil sie Entitäten entfernt).
Ein kurzer Test:
Ergebnis:
Fehlerbehandlung:
&#apos;
die in XML und XHTML gültig sind, jedoch kein einfaches HTML) verursachen eineValueError
Ausnahme.ValueError
Ausnahme.Sicherheitshinweis: Verwechseln Sie HTML-Stripping (Konvertieren von HTML in einfachen Text) nicht mit HTML-Bereinigung (Konvertieren von einfachem Text in HTML). Diese Antwort entfernt HTML und dekodiert Entitäten in einfachen Text - dies macht die Verwendung des Ergebnisses in einem HTML-Kontext nicht sicher.
Beispiel:
<script>alert("Hello");</script>
wird in konvertiert<script>alert("Hello");</script>
, was zu 100% korrekt ist, aber offensichtlich nicht ausreicht, wenn der resultierende Klartext unverändert in eine HTML-Seite eingefügt wird.Die Regel ist nicht schwer: Jedes Mal, wenn Sie eine Nur-Text-Zeichenfolge in die HTML-Ausgabe einfügen, sollten Sie sie immer mit HTML maskieren (mit
cgi.escape(s, True)
), auch wenn Sie "wissen", dass sie kein HTML enthält (z. B. weil Sie HTML-Inhalte entfernt haben). .(Das OP fragte jedoch nach dem Drucken des Ergebnisses auf der Konsole. In diesem Fall ist kein HTML-Escape erforderlich.)
Python 3.4+ Version: (mit Doctest!)
Beachten Sie, dass HTMLParser in Python 3 verbessert wurde (was weniger Code und eine bessere Fehlerbehandlung bedeutet).
quelle
Es gibt einen einfachen Weg dazu:
Die Idee wird hier erklärt: http://youtu.be/2tu9LTDujbw
Sie können es hier sehen: http://youtu.be/HPkNPcYed9M?t=35s
PS - Wenn Sie an der Klasse interessiert sind (über intelligentes Debuggen mit Python), gebe ich Ihnen einen Link: http://www.udacity.com/overview/Course/cs259/CourseRev/1 . Es ist kostenlos!
Bitte! :) :)
quelle
<b class="o'>x</b>
als Eingabefunktion Ausgänge gebenx
. Tatsächlich ist diese Eingabe jedoch ungültig. Ich denke, deshalb bevorzugen die Leute Bibliotheken.Wenn Sie HTML-Entitäten (dh
&
) beibehalten müssen, habe ich Eloffs Antwort die Methode "handle_entityref" hinzugefügt .quelle
Wenn Sie alle HTML-Tags entfernen möchten, ist die Verwendung von BeautifulSoup der einfachste Weg, den ich gefunden habe:
Ich habe den Code der akzeptierten Antwort ausprobiert, aber "RuntimeError: Maximale Rekursionstiefe überschritten" wurde angezeigt, was mit dem obigen Codeblock nicht der Fall war.
quelle
''.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
. Hier ist die Ausgabe "helloworld", während Sie wahrscheinlich möchten, dass es "Hallo Welt" ist.' '.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
hilft nicht, da es "er llo Welt" wird.Eine lxml.html- basierte Lösung (lxml ist eine native Bibliothek und daher viel schneller als jede reine Python-Lösung).
Wenn Sie vor der Konvertierung in Text mehr Kontrolle darüber benötigen, was genau bereinigt wird, können Sie den lxml-Reiniger explizit verwenden, indem Sie die gewünschten Optionen im Konstruktor übergeben, z.
quelle
Hier ist eine einfache Lösung, die HTML-Tags entfernt und HTML-Entitäten basierend auf der erstaunlich schnellen
lxml
Bibliothek dekodiert :quelle
text_content()
kehrt zurück,lxml.etree._ElementUnicodeResult
sodass Sie es möglicherweise zuerst in eine Zeichenfolgestr
für Zeichenfolgenoperationen wie+
und Indizierung automatisch umgewandelt zu werden[]
. Es wurde sowieso eine Besetzung für ein gutes Maß hinzugefügt.Das Beautiful Soup-Paket erledigt dies sofort für Sie.
quelle
Hier ist meine Lösung für Python 3.
Ich bin mir nicht sicher, ob es perfekt ist, habe aber meinen Anwendungsfall gelöst und scheint einfach zu sein.
quelle
Sie können entweder einen anderen HTML-Parser ( wie lxml oder Beautiful Soup ) verwenden, der Funktionen zum Extrahieren von nur Text bietet. Sie können auch einen regulären Ausdruck für Ihre Zeilenzeichenfolge ausführen, mit dem die Tags entfernt werden. Weitere Informationen finden Sie in den Python-Dokumenten .
quelle
lxml.html.fromstring(s).text_content()
&
. B. ) in Text.Ich habe Eloffs Antwort erfolgreich für Python 3.1 verwendet [vielen Dank!].
Ich habe ein Upgrade auf Python 3.2.3 durchgeführt und bin auf Fehler gestoßen.
Die Lösung, die hier dank des Antwortenden Thomas K bereitgestellt wird , besteht darin,
super().__init__()
den folgenden Code einzufügen :... damit es so aussieht:
... und es wird für Python 3.2.3 funktionieren.
Nochmals vielen Dank an Thomas K für das Update und den oben angegebenen Originalcode von Eloff!
quelle
Sie können Ihre eigene Funktion schreiben:
quelle
Die Lösungen mit HTML-Parser sind alle zerbrechlich, wenn sie nur einmal ausgeführt werden:
Ergebnisse in:
was Sie verhindern wollen. Wenn Sie einen HTML-Parser verwenden, zählen Sie die Tags, bis Null ersetzt wird:
quelle
html_to_text
und den von dieser Funktion ausgegebenen Text in HTML einbetten, ohne diesen Text zu maskieren, ist das fehlende Escaping eine Sicherheitslücke, nicht diehtml_to_text
Funktion. Diehtml_to_text
Funktion hat Ihnen nie versprochen, dass die Ausgabe Text sein würde. Das Einfügen von Text in HTML ohne Escapezeichen ist eine potenzielle Sicherheitslücke, unabhängig davon, ob Sie den Text vonhtml_to_text
einer anderen Quelle erhalten haben oder nicht.Dies ist eine schnelle Lösung und kann noch optimiert werden, funktioniert aber einwandfrei. Dieser Code ersetzt alle nicht leeren Tags durch "" und entfernt alle HTML-Tags aus einem bestimmten Eingabetext. Sie können ihn mit der Eingabeausgabe ./file.py ausführen
quelle
Eine Python 3-Adaption der Antwort von søren-løvborg
quelle
Für ein Projekt brauchte ich also HTML-Strip, aber auch CSS und JS. Daher habe ich eine Variation von Eloffs Antwort gemacht:
quelle
Hier ist eine Lösung ähnlich der derzeit akzeptierten Antwort ( https://stackoverflow.com/a/925630/95989 ), außer dass die interne
HTMLParser
Klasse direkt verwendet wird (dh keine Unterklasse), wodurch sie erheblich knapper wird:quelle
Ich analysiere Github Readmes und finde, dass Folgendes wirklich gut funktioniert:
Und dann
Entfernt alle Markdowns und HTML-Dateien korrekt.
quelle
Wenn Sie BeautifulSoup, html2text oder den Code von @Eloff verwenden, bleiben meistens einige HTML-Elemente, Javascript-Code ...
Sie können also eine Kombination dieser Bibliotheken verwenden und die Markdown-Formatierung löschen (Python 3):
Es funktioniert gut für mich, aber es kann natürlich verbessert werden ...
quelle
Einfacher Code!. Dadurch werden alle darin enthaltenen Tags und Inhalte entfernt.
Es wird jedoch kein vollständiges Ergebnis erzielt, wenn der Text <> Symbole enthält .
quelle
quelle
Diese Methode funktioniert bei mir einwandfrei und erfordert keine zusätzlichen Installationen:
quelle