from mechanize import Browser
br = Browser()
br.open('http://somewebpage')
html = br.response().readlines()
for line in html:
print line
Podczas drukowania linii w pliku HTML próbuję znaleźć sposób, aby wyświetlić tylko zawartość każdego elementu HTML, a nie samo formatowanie. Jeśli znajdzie '<a href="whatever.com">some text</a>'
, wydrukuje tylko „trochę tekstu”, '<b>hello</b>'
drukuje „cześć” itd. Jak by to zrobić?
&
.). Możesz albo 1) usunąć je wraz ze znacznikami (często niepożądane i niepotrzebne, ponieważ są one równoważne zwykłemu tekstowi), 2) pozostawić je bez zmian (odpowiednie rozwiązanie, jeśli rozebrany tekst wraca z powrotem do kontekstu HTML) lub 3 ) zdekoduj je do zwykłego tekstu (jeśli rozebrany tekst trafia do bazy danych lub do innego kontekstu innego niż HTML, lub jeśli Twoja platforma internetowa automatycznie wykonuje dla Ciebie znaki ucieczki HTML).Odpowiedzi:
Zawsze używałem tej funkcji do usuwania tagów HTML, ponieważ wymaga ona tylko stdlib w Pythonie:
W przypadku Python 3:
W przypadku Python 2:
źródło
&
) Oraz znaczników.__init__
. Zobacz tutaj: stackoverflow.com/questions/11061058/... .parser = HTMLParser()
ihtml = parser.unescape(html)
na początku funkcji strip_tags.Nie myślałem zbyt wiele o przypadkach, w których będzie brakować, ale możesz zrobić prosty regex:
Dla tych, którzy nie rozumieją wyrażenia regularnego, szuka łańcucha
<...>
, w którym wewnętrzna zawartość składa się z co najmniej jednego (+
) znaku, który nie jest<
. Te?
środki, które będą pasować najmniejszy łańcuch można go znaleźć. Na przykład<p>Hello</p>
, będzie pasował<'p>
i</p>
osobno z?
. Bez niego dopasuje cały ciąg<..Hello..>
.Jeśli nietag
<
pojawia się w html (np.2 < 3
), I tak powinien zostać zapisany jako sekwencja ucieczki,&...
więc^<
może być niepotrzebny.źródło
&
) Niezmienione w danych wyjściowych.cgi.escape(s, True)
), nawet jeśli wiesz, że nie zawiera HTML (np. Ponieważ usunąłeś treść HTML) . Jednak nie o to pytał OP.Możesz użyć
get_text()
funkcji BeautifulSoup .Wskazane jest jawne określenie analizatora składni , na przykład jako
BeautifulSoup(html_str, features="html.parser")
, aby dane wyjściowe były odtwarzalne.źródło
Krótka wersja!
Źródło Regex: MarkupSafe . Ich wersja obsługuje również encje HTML, podczas gdy ta szybka nie.
Dlaczego nie mogę po prostu usunąć tagów i zostawić go?
To jedna rzecz, aby powstrzymać ludzi przed
<i>italicizing</i>
rzeczami, nie pozostawiająci
pływających. Ale to kolejna rzecz, aby wziąć arbitralny wkład i uczynić go całkowicie nieszkodliwym. Większość technik na tej stronie pozostawia niezmienione niezamknięte komentarze (<!--
) i nawiasy kątowe, które nie są częścią tagów (blah <<<><blah
). Wersja HTMLParser może nawet pozostawić pełne tagi, jeśli znajdują się w niezamkniętym komentarzu.Co jeśli twój szablon jest
{{ firstname }} {{ lastname }}
?firstname = '<a'
ilastname = 'href="http://evil.com/">'
zostaną przepuszczone przez wszystkie narzędzia do usuwania tagów na tej stronie (z wyjątkiem @Medeiros!), ponieważ same nie są kompletnymi tagami. Usunięcie zwykłych tagów HTML nie wystarczy.Django
strip_tags
, ulepszona (patrz następny nagłówek) wersja najważniejszej odpowiedzi na to pytanie, daje następujące ostrzeżenie:Postępuj zgodnie z ich radami!
Aby usunąć tagi za pomocą HTMLParser, musisz uruchomić go wiele razy.
Łatwo jest ominąć najwyższą odpowiedź na to pytanie.
Spójrz na ten ciąg ( źródło i dyskusja ):
Gdy HTMLParser widzi go po raz pierwszy, nie może stwierdzić, że
<img...>
jest to tag. Wygląda na zepsuty, więc HTMLParser się go nie pozbywa. To tylko usuwa<!-- comments -->
, pozostawiając cię zProblem ten został ujawniony projektowi Django w marcu 2014 roku. Ich stary
strip_tags
był zasadniczo taki sam jak najlepsza odpowiedź na to pytanie. Ich nowa wersja zasadniczo uruchamia go w pętli, dopóki ponowne uruchomienie nie zmieni łańcucha:Oczywiście nic z tego nie stanowi problemu, jeśli zawsze unikniesz wyniku
strip_tags()
.Aktualizacja 19 marca 2015 r . : Wystąpił błąd w wersjach Django przed 1.4.20, 1.6.11, 1.7.7 i 1.8c1. Te wersje mogą wejść w nieskończoną pętlę w funkcji strip_tags (). Naprawiona wersja została odtworzona powyżej. Więcej informacji tutaj .
Dobre rzeczy do skopiowania lub użycia
Mój przykładowy kod nie obsługuje encji HTML - robią to wersje spakowane Django i MarkupSafe.
Mój przykładowy kod został pobrany z doskonałej biblioteki MarkupSafe w celu zapobiegania skryptom krzyżowym. Jest wygodny i szybki (dzięki przyspieszeniom języka C do natywnej wersji Pythona). Jest zawarty w Google App Engine i jest używany przez Jinja2 (wersja 2.7 i nowsze) , Mako, Pylony i inne. Działa łatwo z szablonami Django z Django 1.7.
Strip_tags Django i inne narzędzia HTML z najnowszej wersji są dobre, ale uważam je za mniej wygodne niż MarkupSafe. Są dość samodzielne, możesz skopiować to, czego potrzebujesz z tego pliku .
Jeśli chcesz usunąć prawie wszystkie znaczniki, biblioteka Bleach jest dobra. Możesz wymusić egzekwowanie reguł takich jak „moi użytkownicy mogą pisać kursywą, ale nie mogą tworzyć ramek iframe”.
Poznaj właściwości swojego narzędzia do usuwania tagów! Uruchom na nim testy Fuzz! Oto kod, którego użyłem do badania tej odpowiedzi.
zawstydzona uwaga - samo pytanie dotyczy drukowania na konsoli, ale jest to najlepszy wynik Google dla „python strip html from string”, dlatego właśnie ta odpowiedź dotyczy 99% internetu.
źródło
Potrzebowałem sposobu, aby rozebrać tagi i zdekodować encje HTML na zwykły tekst. Poniższe rozwiązanie oparte jest na odpowiedzi Eloffa (której nie mogłem użyć, ponieważ usuwa byty).
Szybki test:
Wynik:
Obsługa błędów:
&#apos;
, które są poprawne w XML i XHTML, ale nie zwykły HTML) spowodująValueError
wyjątek.ValueError
wyjątek.Uwaga dotycząca bezpieczeństwa: nie należy mylić rozbiórki HTML (konwersja HTML na zwykły tekst) z odkażaniem HTML (konwersja zwykłego tekstu na HTML). Ta odpowiedź usunie HTML i zdekoduje jednostki na zwykły tekst - co nie sprawia, że wynik jest bezpieczny w użyciu w kontekście HTML.
Przykład:
<script>alert("Hello");</script>
zostanie przekonwertowany na<script>alert("Hello");</script>
, co jest w 100% poprawnym zachowaniem, ale oczywiście niewystarczające, jeśli wynikowy zwykły tekst zostanie wstawiony w niezmienionej postaci na stronie HTML.Zasada nie jest trudna: za każdym razem , gdy wstawiasz ciąg tekstowy do wyjścia HTML, zawsze powinieneś go unikać (używając
cgi.escape(s, True)
), nawet jeśli wiesz, że nie zawiera HTML (np. Ponieważ usunąłeś treść HTML) .(Jednak OP poprosił o wydrukowanie wyniku na konsoli, w którym to przypadku nie jest wymagane ucieczka HTML).
Wersja Python 3.4+: (z doctest!)
Zauważ, że HTMLParser poprawił się w Pythonie 3 (co oznacza mniej kodu i lepszą obsługę błędów).
źródło
Jest na to prosty sposób:
Pomysł wyjaśniono tutaj: http://youtu.be/2tu9LTDujbw
Możesz zobaczyć, jak działa tutaj: http://youtu.be/HPkNPcYed9M?t=35s
PS - Jeśli jesteś zainteresowany klasą (o inteligentnym debugowaniu za pomocą Pythona), dam ci link: http://www.udacity.com/overview/Course/cs259/CourseRev/1 . Jest wolne!
Nie ma za co! :)
źródło
<b class="o'>x</b>
jako dane wyjściowe funkcji wejściowychx
. Ale tak naprawdę to wejście jest nieprawidłowe. Myślę, że dlatego ludzie wolą biblioteki lib.Jeśli chcesz zachować encje HTML (tj.
&
), Dodałem metodę „handle_entityref” do odpowiedzi Eloffa .źródło
Jeśli chcesz usunąć wszystkie tagi HTML, najłatwiejszym sposobem, jaki znalazłem, jest użycie BeautifulSoup:
Próbowałem kodu akceptowanej odpowiedzi, ale otrzymywałem komunikat „RuntimeError: przekroczona maksymalna głębokość rekurencji”, co nie zdarzyło się w przypadku powyższego bloku kodu.
źródło
''.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
. Tutaj wyjściem jest „helloworld”, podczas gdy prawdopodobnie chcesz, aby był to „hello world”.' '.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
nie pomaga, ponieważ staje się „on llo world”.Oto proste rozwiązanie, które usuwa tagi HTML i dekoduje encje HTML w oparciu o niezwykle szybką
lxml
bibliotekę:źródło
text_content()
zwraca,lxml.etree._ElementUnicodeResult
więc być może będziesz musiał najpierw rzucić go na stringstr
na operacje łańcuchowe, takie jak+
i indeksowanie[]
. W każdym razie dodano obsadę dla dobrego pomiaru.Lxml.html rozwiązanie -na (lxml jest natywna biblioteka, a więc znacznie szybciej niż w jakimkolwiek czystym roztworze Pythona).
Jeśli potrzebujesz większej kontroli nad tym, co dokładnie jest dezynfekowane przed konwersją na tekst, możesz użyć lxml Cleaner jawnie, przekazując odpowiednie opcje w konstruktorze, np .:
źródło
Pakiet Pięknej Zupy robi to natychmiast.
źródło
Oto moje rozwiązanie dla Pythona 3.
Nie jestem pewien, czy jest idealny, ale rozwiązałem mój przypadek użycia i wydaje się prosty.
źródło
Możesz użyć innego parsera HTML ( takiego jak lxml lub Beautiful Soup ) - takiego, który oferuje funkcje do wyodrębnienia samego tekstu. Lub możesz uruchomić wyrażenie regularne na łańcuchu linii, który usuwa tagi. Zobacz dokumentację Python, aby uzyskać więcej.
źródło
lxml.html.fromstring(s).text_content()
&
) Na tekst.Z powodzeniem wykorzystałem odpowiedź Eloffa dla Pythona 3.1 [wielkie dzięki!].
Uaktualniłem do Python 3.2.3 i napotkałem błędy.
Rozwiązaniem udostępnionym tutaj dzięki respondentowi Thomasowi K jest wstawienie
super().__init__()
do następującego kodu:... aby wyglądało to tak:
... i będzie działać dla Python 3.2.3.
Ponownie, dzięki Thomasowi K za poprawkę i za oryginalny kod Eloffa podany powyżej!
źródło
Możesz napisać własną funkcję:
źródło
Wszystkie rozwiązania z parserem HTML są łamliwe, jeśli działają tylko raz:
prowadzi do:
co zamierzasz zapobiec. jeśli używasz parsera HTML, policz tagi, aż zero zostanie zastąpione:
źródło
html_to_text
i osadzisz tekst wyprowadzany z tej funkcji w html bez zmiany znaczenia tego tekstu, to brak ucieczki jest zagrożeniem bezpieczeństwa, a niehtml_to_text
funkcja.html_to_text
Funkcja nigdy nie obiecał, wyjście będzie tekst. A wstawianie tekstu do html bez ucieczki stanowi potencjalną lukę w zabezpieczeniach niezależnie od tego, czy tekst został pobrany,html_to_text
czy z innego źródła.Jest to szybka poprawka i może być jeszcze bardziej zoptymalizowana, ale będzie działać dobrze. Ten kod zastąpi wszystkie niepuste tagi „” i usuwa wszystkie tagi html z podanego tekstu wejściowego. Możesz uruchomić go za pomocą pliku wyjściowego ./file.py
źródło
Adaptacja 3 w pytaniu odpowiedzi søren-løvborg
źródło
Do jednego projektu potrzebowałem więc rozebrać HTML, ale także css i js. Dlatego zrobiłem odmianę odpowiedzi Eloffa:
źródło
Oto rozwiązanie podobne do obecnie akceptowanej odpowiedzi ( https://stackoverflow.com/a/925630/95989 ), z tym wyjątkiem, że korzysta
HTMLParser
bezpośrednio z klasy wewnętrznej (tj. Bez podklasy), dzięki czemu jest znacznie bardziej zwięzły:źródło
Analizuję readmesy Github i stwierdzam, że następujące działania naprawdę działają dobrze:
I wtedy
Usuwa wszystkie obniżki i HTML poprawnie.
źródło
Używając BeautifulSoup, html2text lub kodu z @Eloff, przez większość czasu pozostaje trochę elementów HTML, kod javascript ...
Możesz więc użyć kombinacji tych bibliotek i usunąć formatowanie przeceny (Python 3):
Działa dla mnie dobrze, ale można go oczywiście ulepszyć ...
źródło
Prosty kod !. Spowoduje to usunięcie wszelkiego rodzaju tagów i treści w nim zawartych.
Ale nie da pełnego wyniku, jeśli tekst zawiera symbole <> .
źródło
źródło
Ta metoda działa dla mnie bezbłędnie i nie wymaga żadnych dodatkowych instalacji:
źródło