from mechanize import Browser
br = Browser()
br.open('http://somewebpage')
html = br.response().readlines()
for line in html:
print line
Saat mencetak baris dalam file HTML, saya mencoba menemukan cara untuk hanya menampilkan konten dari setiap elemen HTML dan bukan formatnya sendiri. Jika ditemukan '<a href="whatever.com">some text</a>'
, itu hanya akan mencetak 'beberapa teks', '<b>hello</b>'
mencetak 'halo', dll. Bagaimana cara melakukannya?
&
). Anda dapat 1) menghapusnya bersama dengan tag (sering tidak diinginkan, dan tidak perlu karena mereka setara dengan teks biasa), 2) membiarkannya tidak berubah (solusi yang sesuai jika teks yang dilucuti akan segera kembali ke konteks HTML) atau 3 ) decode mereka ke teks biasa (jika teks yang dilucuti pergi ke database atau konteks non-HTML lainnya, atau jika kerangka web Anda secara otomatis melakukan pelolosan HTML teks untuk Anda).Jawaban:
Saya selalu menggunakan fungsi ini untuk menghapus tag HTML, karena hanya membutuhkan stdlib Python:
Untuk Python 3:
Untuk Python 2:
sumber
&
) dan juga tag.__init__
fungsi kelas induk . Lihat di sini: stackoverflow.com/questions/11061058/… .parser = HTMLParser()
danhtml = parser.unescape(html)
ke awal fungsi strip_tags.Saya belum berpikir banyak tentang kasus-kasus yang akan hilang, tetapi Anda dapat melakukan regex sederhana:
Bagi mereka yang tidak mengerti regex, ini mencari string
<...>
, di mana konten dalam terbuat dari satu atau lebih (+
) karakter yang bukan a<
. The?
berarti bahwa itu akan cocok dengan string terkecil dapat ditemukan. Misalnya diberikan<p>Hello</p>
, itu akan cocok<'p>
dan</p>
secara terpisah dengan?
. Tanpanya, itu akan cocok dengan seluruh string<..Hello..>
.Jika non-tag
<
muncul dalam html (mis.2 < 3
), Itu harus ditulis sebagai urutan escape&...
sehingga^<
mungkin tidak perlu.sumber
&
) Tidak berubah dalam output.cgi.escape(s, True)
), bahkan jika Anda "tahu" bahwa itu tidak mengandung HTML (misalnya karena Anda menghapus konten HTML) . Namun, ini bukan yang ditanyakan OP.Anda dapat menggunakan
get_text()
fitur BeautifulSoup .Dianjurkan untuk secara eksplisit menentukan parser , misalnya sebagai
BeautifulSoup(html_str, features="html.parser")
, untuk output yang akan direproduksi.sumber
Versi pendek!
Sumber regex: MarkupSafe . Versi mereka menangani entitas HTML juga, sedangkan yang cepat ini tidak.
Mengapa saya tidak bisa menghapus tag saja dan membiarkannya?
Adalah satu hal untuk menjauhkan orang dari
<i>italicizing</i>
berbagai hal, tanpa meninggalkani
yang mengambang. Tapi mengambil input sewenang-wenang dan membuatnya sama sekali tidak berbahaya. Sebagian besar teknik pada halaman ini akan membuat hal-hal seperti komentar tertutup (<!--
) dan kurung sudut yang bukan bagian dari tag (blah <<<><blah
) tetap utuh. Versi HTMLParser bahkan dapat meninggalkan tag lengkap, jika ada di dalam komentar tidak tertutup.Bagaimana jika templat Anda
{{ firstname }} {{ lastname }}
?firstname = '<a'
danlastname = 'href="http://evil.com/">'
akan diizinkan masuk oleh setiap stripper tag pada halaman ini (kecuali @Medeiros!), karena mereka tidak menyelesaikan tag sendiri. Menghapus tag HTML normal tidak cukup.Django
strip_tags
, versi yang lebih baik (lihat tajuk berikutnya) dari jawaban atas pertanyaan ini, memberikan peringatan berikut:Ikuti saran mereka!
Untuk menghapus tag dengan HTMLParser, Anda harus menjalankannya beberapa kali.
Sangat mudah untuk mengelak dari jawaban teratas untuk pertanyaan ini.
Lihat string ini ( sumber dan diskusi ):
Pertama kali HTMLParser melihatnya, ia tidak bisa memastikan bahwa itu
<img...>
adalah sebuah tag. Itu terlihat rusak, jadi HTMLParser tidak menghilangkannya. Hanya mengeluarkan<!-- comments -->
, meninggalkan Anda denganMasalah ini diungkapkan kepada proyek Django pada bulan Maret 2014. Yang lama
strip_tags
pada dasarnya sama dengan jawaban teratas untuk pertanyaan ini. Versi baru mereka pada dasarnya menjalankannya dalam satu lingkaran sampai menjalankannya lagi tidak mengubah string:Tentu saja, semua ini bukan masalah jika Anda selalu luput dari hasilnya
strip_tags()
.Pembaruan 19 Maret 2015 : Ada bug dalam versi Django sebelum 1.4.20, 1.6.11, 1.7.7, dan 1.8c1. Versi ini dapat memasukkan infinite loop dalam fungsi strip_tags (). Versi tetap direproduksi di atas. Lebih detail di sini .
Hal-hal baik untuk disalin atau digunakan
Kode contoh saya tidak menangani entitas HTML - versi paket Django dan MarkupSafe lakukan.
Contoh kode saya diambil dari perpustakaan MarkupSafe yang sangat baik untuk pencegahan skrip lintas situs. Lebih mudah dan cepat (dengan speedup C ke versi Python aslinya). Ini termasuk dalam Google App Engine , dan digunakan oleh Jinja2 (2.7 dan lebih tinggi) , Mako, Pylons, dan banyak lagi. Ini bekerja dengan mudah dengan template Django dari Django 1.7.
Strip_tags Django dan utilitas html lainnya dari versi terbaru bagus, tapi saya merasa mereka kurang nyaman daripada MarkupSafe. Mereka cukup mandiri, Anda dapat menyalin apa yang Anda butuhkan dari file ini .
Jika Anda perlu menghapus hampir semua tag, perpustakaan Bleach bagus. Anda dapat menerapkannya seperti "pengguna saya dapat membuat huruf miring, tetapi mereka tidak bisa membuat iframe."
Pahami properti stripper tag Anda! Jalankan tes fuzz di atasnya! Berikut adalah kode yang saya gunakan untuk melakukan penelitian untuk jawaban ini.
catatan lamban - Pertanyaannya sendiri adalah tentang mencetak ke konsol, tapi ini adalah hasil Google teratas untuk "python strip html dari string", jadi itu sebabnya jawaban ini 99% tentang web.
sumber
Saya membutuhkan cara untuk menghapus tag dan mendekode entitas HTML menjadi teks biasa. Solusi berikut ini didasarkan pada jawaban Eloff (yang tidak bisa saya gunakan karena menghapus entitas).
Tes cepat:
Hasil:
Menangani kesalahan:
&#apos;
, yang valid dalam XML dan XHTML, tetapi tidak HTML biasa) akan menyebabkanValueError
pengecualian.ValueError
pengecualian.Catatan keamanan: Jangan bingung stripping HTML (mengubah HTML menjadi teks biasa) dengan sanitasi HTML (mengubah teks biasa menjadi HTML). Jawaban ini akan menghapus HTML dan mendekode entitas ke dalam teks biasa - yang tidak membuat hasilnya aman untuk digunakan dalam konteks HTML.
Contoh:
<script>alert("Hello");</script>
akan dikonversi menjadi<script>alert("Hello");</script>
, yang merupakan perilaku 100% benar, tetapi jelas tidak cukup jika teks biasa yang dihasilkan dimasukkan apa adanya ke halaman HTML.Aturannya tidak sulit: Setiap kali Anda memasukkan string teks biasa ke dalam output HTML, Anda harus selalu menghindarinya dari HTML (menggunakan
cgi.escape(s, True)
), bahkan jika Anda "tahu" bahwa itu tidak mengandung HTML (misalnya karena Anda menghapus konten HTML) .(Namun, OP bertanya tentang mencetak hasilnya ke konsol, dalam hal ini tidak diperlukan pelolosan HTML.)
Versi Python 3.4+: (dengan doctest!)
Perhatikan bahwa HTMLParser telah meningkat dalam Python 3 (artinya lebih sedikit kode dan penanganan kesalahan yang lebih baik).
sumber
Ada cara sederhana untuk ini:
Idenya dijelaskan di sini: http://youtu.be/2tu9LTDujbw
Anda dapat melihatnya berfungsi di sini: http://youtu.be/HPkNPcYed9M?t=35s
PS - Jika Anda tertarik pada kelas (tentang debugging pintar dengan python) saya beri Anda tautan: http://www.udacity.com/overview/Course/cs259/CourseRev/1 . Gratis!
Sama-sama! :)
sumber
<b class="o'>x</b>
output fungsi inputx
. Namun sebenarnya input ini tidak valid. Saya pikir itu sebabnya orang lebih suka lib.Jika Anda perlu mempertahankan entitas HTML (yaitu
&
), saya menambahkan metode "handle_entityref" ke jawaban Eloff .sumber
Jika Anda ingin menghapus semua tag HTML, cara termudah yang saya temukan adalah menggunakan BeautifulSoup:
Saya mencoba kode jawaban yang diterima tetapi saya mendapatkan "RuntimeError: kedalaman rekursi maksimum terlampaui", yang tidak terjadi dengan blok kode di atas.
sumber
''.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
. Di sini outputnya adalah "helloworld", sementara Anda mungkin menginginkannya menjadi "halo dunia".' '.join(BeautifulSoup('<em>he</em>llo<br>world').find_all(text=True))
tidak membantu karena menjadi "dia llo dunia".Berikut adalah solusi sederhana yang menghapus tag HTML dan menerjemahkan entitas HTML berdasarkan
lxml
pustaka yang luar biasa cepat :sumber
text_content()
kembalilxml.etree._ElementUnicodeResult
sehingga Anda mungkin harus melemparkannya ke string terlebih dahulustr
untuk operasi string seperti+
dan pengindeksan[]
. Menambahkan gips untuk ukuran yang baik bagaimanapun.Sebuah lxml.html solusi berbasis (lxml adalah perpustakaan asli dan karena itu jauh lebih cepat daripada solusi python murni).
Jika Anda memerlukan kontrol lebih besar atas apa sebenarnya yang disanitasi sebelum mengonversi ke teks maka Anda mungkin ingin menggunakan Pembersih lxml secara eksplisit dengan meneruskan opsi yang Anda inginkan dalam konstruktor, misalnya:
sumber
Paket Beautiful Soup segera melakukan ini untuk Anda.
sumber
Inilah solusi saya untuk python 3.
Tidak yakin apakah itu sempurna, tetapi memecahkan kasus penggunaan saya dan tampaknya sederhana.
sumber
Anda dapat menggunakan parser HTML yang berbeda ( seperti lxml , atau Beautiful Soup ) - yang menawarkan fungsi untuk mengekstrak hanya teks. Atau, Anda dapat menjalankan regex pada string baris Anda yang menghapus tag. Lihat dokumen Python untuk lebih lanjut.
sumber
lxml.html.fromstring(s).text_content()
&
) ke teks.Saya telah menggunakan jawaban Eloff dengan sukses untuk Python 3.1 [terima kasih banyak!].
Saya memutakhirkan ke Python 3.2.3, dan mengalami kesalahan.
Solusinya, yang disediakan di sini berkat responden Thomas K, adalah dengan memasukkan
super().__init__()
kode berikut:... agar terlihat seperti ini:
... dan itu akan berfungsi untuk Python 3.2.3.
Sekali lagi, terima kasih kepada Thomas K untuk perbaikan dan untuk kode asli Eloff yang disediakan di atas!
sumber
Anda dapat menulis fungsi Anda sendiri:
sumber
Solusi dengan HTML-Parser dapat dipecahkan, jika dijalankan hanya sekali:
menghasilkan:
apa yang ingin Anda cegah. jika Anda menggunakan HTML-Parser, hitung Tag sampai nol diganti:
sumber
html_to_text
dan Anda menanamkan teks yang menjadi output dari fungsi itu di dalam html tanpa melarikan diri teks itu, maka itu adalah kurangnya melarikan diri, yang merupakan kerentanan keamanan, bukanhtml_to_text
fungsi. Thehtml_to_text
Fungsi pernah menjanjikan Anda output akan teks. Dan memasukkan teks ke dalam html tanpa melarikan diri adalah potensi kerentanan keamanan terlepas dari apakah Anda mendapatkan teks darihtml_to_text
atau sumber lain.Ini adalah perbaikan cepat dan bahkan dapat lebih dioptimalkan tetapi akan berfungsi dengan baik. Kode ini akan mengganti semua tag yang tidak kosong dengan "" dan menghapus semua tag html dari teks input yang diberikan. Anda dapat menjalankannya menggunakan ./file.py input output
sumber
A python 3 adaptasi dari jawaban søren-løvborg
sumber
Untuk satu proyek, saya perlu strip HTML, tetapi juga css dan js. Jadi, saya membuat variasi dari jawaban Eloff:
sumber
Berikut adalah solusi yang mirip dengan jawaban yang saat ini diterima ( https://stackoverflow.com/a/925630/95989 ), kecuali bahwa ia menggunakan
HTMLParser
kelas internal secara langsung (yaitu tidak ada subklasifikasi), sehingga membuatnya secara signifikan lebih singkat:sumber
Saya parsing readmes Github dan saya menemukan bahwa berikut ini benar-benar berfungsi dengan baik:
Lalu
Hapus semua penurunan harga dan html dengan benar.
sumber
Menggunakan BeautifulSoup, html2text atau kode dari @ Eloff, sebagian besar waktu, itu tetap beberapa elemen html, kode javascript ...
Jadi, Anda dapat menggunakan kombinasi dari pustaka ini dan menghapus pemformatan penurunan harga (Python 3):
Ini bekerja dengan baik untuk saya tetapi dapat ditingkatkan, tentu saja ...
sumber
Kode sederhana !. Ini akan menghapus semua jenis tag dan konten di dalamnya.
Tapi itu tidak akan memberikan hasil penuh jika teks berisi <> simbol di dalamnya.
sumber
sumber
Metode ini berfungsi dengan sempurna untuk saya dan tidak memerlukan instalasi tambahan:
sumber