Parser BeautifulSoup 3.1 terlalu mudah rusak

Saya kesulitan mengurai beberapa HTML yang cerdik dengan BeautifulSoup. Ternyata HTMLParser yang digunakan di versi yang lebih baru kurang toleran dibandingkan SGMLParser yang digunakan sebelumnya.


Apakah BeautifulSoup memiliki semacam mode debug? Saya mencoba mencari cara untuk menghentikannya membosankan pada beberapa HTML jahat yang saya muat dari situs web pemarah:

<HTML>
    <HEAD>
        <TITLE>Title</TITLE>
        <HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
    </HEAD>
    <BODY>
        ...
        ...
    </BODY>
</HTML>

BeautifulSoup menyerah setelah tag <HTTP-EQUIV...>

In [1]: print BeautifulSoup(c).prettify()
<html>
 <head>
  <title>
   Title
  </title>
 </head>
</html>

Masalahnya jelas pada tag HTTP-EQUIV, yang sebenarnya merupakan tag <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"> yang sangat salah. Jelas, saya perlu menetapkan ini sebagai penutupan sendiri, tetapi apa pun yang saya tentukan, saya tidak dapat memperbaikinya:

In [2]: print BeautifulSoup(c,selfClosingTags=['http-equiv',
                            'http-equiv="pragma"']).prettify()
<html>
 <head>
  <title>
   Title
  </title>
 </head>
</html>

Apakah ada mode debug verbose di mana BeautifulSoup akan memberi tahu saya apa yang dilakukannya, sehingga saya dapat mengetahui apa yang diperlakukan sebagai nama tag dalam kasus ini?


person Mat    schedule 19.01.2009    source sumber


Jawaban (3)


Masalah Anda pasti ada hal lain; itu berfungsi dengan baik untuk saya:

In [1]: import BeautifulSoup

In [2]: c = """<HTML>
   ...:     <HEAD>
   ...:         <TITLE>Title</TITLE>
   ...:         <HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
   ...:     </HEAD>
   ...:     <BODY>
   ...:         ...
   ...:         ...
   ...:     </BODY>
   ...: </HTML>
   ...: """

In [3]: print BeautifulSoup.BeautifulSoup(c).prettify()
<html>
 <head>
  <title>
   Title
  </title>
  <http-equiv>
  </http-equiv>
 </head>
 <body>
  ...
        ...
 </body>
</html>


In [4]: 

Ini adalah Python 2.5.2 dengan BeautifulSoup 3.0.7a — mungkin berbeda di versi lama/baru? Ini persis dengan jenis sup yang ditangani BeautifulSoup dengan begitu indah, jadi saya ragu sup ini pernah diubah… Apakah ada hal lain pada struktur yang belum Anda sebutkan dalam soal?

person ShreevatsaR    schedule 19.01.2009
comment
Saya punya Python 2.5.1 dan BeautifulSoup 3.1.0.1. Struktur rusak aslinya berbeda, tetapi masalahnya juga terjadi pada struktur yang disederhanakan dalam pertanyaan. Saya baru saja menjalankan kode dalam contoh Anda dan mengalami masalah yang sama seperti sebelumnya, tidak ada masalah setelah ‹/title›. Sekarang aku benar-benar bingung! - person Mat; 20.01.2009
comment
Salah satu kemungkinannya adalah BeautifulSoup merusak sesuatu saat memperbarui... apakah Anda mencoba dengan teks yang disalin persis dari pertanyaan Anda di sini? - person ShreevatsaR; 20.01.2009
comment
crummy.com/software/BeautifulSoup/CHANGELOG.html BeautifulSoup 3.1 didasarkan pada HTMLParser, bukan SGMLParser (karena SGMLParser sudah tidak ada di Python 3.0), yang mungkin menjadi masalahnya di sini. Itu menyedihkan... - person ShreevatsaR; 20.01.2009
comment
Ya, saya mencoba dengan teks yang sama persis dengan pertanyaan, dan saya baru saja menyalin dan menempelkannya lagi untuk memastikan. Kedengarannya menyedihkan karena parser telah diubah. Mungkin saya harus memasukkan ekspresi reguler cepat untuk menghilangkan HTML yang rusak. Bukannya saya akan menemukan hal serupa di tempat lain. - person Mat; 20.01.2009

Memiliki masalah dengan Beautiful Soup 3.1.0? merekomendasikan untuk menggunakan html5lib sebagai salah satu solusi.

#!/usr/bin/env python
from html5lib import HTMLParser, treebuilders

parser = HTMLParser(tree=treebuilders.getTreeBuilder("beautifulsoup"))

c = """<HTML>
    <HEAD>
        <TITLE>Title</TITLE>
        <HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
    </HEAD>
    <BODY>
        ...
        ...
    </BODY>
</HTML>"""

soup = parser.parse(c)
print soup.prettify()

Keluaran:

<html>
 <head>
  <title>
   Title
  </title>
 </head>
 <body>
  <http-equiv="pragma" content="NO-CACHE">
   ...
        ...
  </http-equiv="pragma">
 </body>
</html>

Outputnya menunjukkan bahwa html5lib belum memperbaiki masalah dalam kasus ini.

person jfs    schedule 12.03.2009

Coba lxml (dan modul htmlnya). Terlepas dari namanya, ini juga untuk parsing dan scraping HTML. Ini jauh lebih cepat daripada BeautifulSoup, dan bahkan menangani HTML yang "rusak" lebih baik daripada BeautifulSoup. Ia juga memiliki API kompatibilitas untuk BeautifulSoup jika Anda tidak ingin mempelajari API lxml.

Ian Blicking setuju.

Tidak ada alasan untuk menggunakan BeautifulSoup lagi, kecuali Anda menggunakan Google App Engine atau sesuatu yang tidak mengizinkan apa pun yang bukan murni Python.

person aehlke    schedule 03.08.2009