ตัวแยกวิเคราะห์ BeautifulSoup 3.1 แตกง่ายเกินไป

ฉันประสบปัญหาในการแยกวิเคราะห์ HTML ที่ไม่น่าเชื่อถือด้วย BeautifulSoup ปรากฎว่า HTMLParser ที่ใช้ในเวอร์ชันที่ใหม่กว่ามีความทนทานน้อยกว่า SGMLParser ที่ใช้ก่อนหน้านี้


BeautifulSoup มีโหมดแก้ไขจุดบกพร่องบ้างไหม? ฉันกำลังพยายามหาวิธีหยุดมันด้วย HTML ที่น่ารังเกียจที่ฉันโหลดจากเว็บไซต์ที่น่ารังเกียจ:

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

BeautifulSoup ยอมแพ้หลังจากแท็ก <HTTP-EQUIV...>

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

ปัญหาอยู่ที่แท็ก HTTP-EQUIV อย่างชัดเจน ซึ่งเป็นแท็ก <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"> ที่มีรูปแบบ มาก เห็นได้ชัดว่าฉันต้องระบุสิ่งนี้ว่าเป็นการปิดตัวเอง แต่ไม่ว่าฉันระบุอะไรก็ไม่สามารถแก้ไขได้:

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

มีโหมดดีบักแบบละเอียดที่ BeautifulSoup จะบอกฉันว่ากำลังทำอะไรอยู่ เพื่อที่ฉันจะได้รู้ว่าในกรณีนี้จะถือเป็นชื่อแท็กอย่างไร


person Mat    schedule 19.01.2009    source แหล่งที่มา


คำตอบ (3)


ปัญหาของคุณต้องเป็นอย่างอื่น มันทำงานได้ดีสำหรับฉัน:

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]: 

นี่คือ Python 2.5.2 พร้อม BeautifulSoup 3.0.7a - อาจจะแตกต่างในเวอร์ชันเก่าหรือใหม่กว่า นี่เป็นซุปประเภทที่ BeautifulSoup จัดการได้อย่างสวยงามมาก ดังนั้นฉันสงสัยว่ามันมีการเปลี่ยนแปลงในจุดใดจุดหนึ่ง… มีอะไรอีกในโครงสร้างที่คุณไม่ได้กล่าวถึงในปัญหาหรือไม่?

person ShreevatsaR    schedule 19.01.2009
comment
ฉันมี Python 2.5.1 และ BeautifulSoup 3.1.0.1 โครงสร้างที่เสียหายดั้งเดิมนั้นแตกต่างออกไป แต่ปัญหาก็เกิดขึ้นกับโครงสร้างที่เรียบง่ายในคำถามด้วย ฉันเพิ่งรันโค้ดในตัวอย่างของคุณและพบปัญหาเหมือนเดิม ไม่มีอะไรอยู่หลัง ‹/title› ตอนนี้ฉันสับสนมาก! - person Mat; 20.01.2009
comment
ความเป็นไปได้ประการหนึ่งก็คือ BeautifulSoup ทำบางอย่างเสียหายเมื่ออัปเดต... คุณลองใช้ข้อความที่คัดลอกมาจากคำถามของคุณที่นี่ทุกประการหรือไม่ - person ShreevatsaR; 20.01.2009
comment
crummy.com/software/BeautifulSoup/CHANGELOG.html BeautifulSoup 3.1 มีพื้นฐานมาจาก HTMLParser แทนที่จะเป็น SGMLParser (เนื่องจากอย่างหลังหายไปใน Python 3.0) ซึ่งอาจเป็นปัญหาที่นี่ เรื่องน่าเศร้า... - person ShreevatsaR; 20.01.2009
comment
ใช่ ฉันลองใช้ข้อความที่ตรงกันทุกประการในคำถามแล้ว และฉันเพิ่งคัดลอกและวางอีกครั้งเพื่อให้แน่ใจ ฟังดูเหมือนความเจ็บปวดที่ parser เปลี่ยนไป บางทีฉันควรจะทิ้งนิพจน์ทั่วไปอย่างรวดเร็วเพื่อโจมตี HTML ที่น่าเบื่อ ไม่ใช่ว่าฉันจะเจอสิ่งที่คล้ายกันที่อื่น - person Mat; 20.01.2009

มีปัญหากับ Beautiful Soup 3.1.0 หรือไม่ แนะนำให้ใช้ html5lib เป็นหนึ่งในวิธีแก้ไขปัญหาชั่วคราว

#!/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()

เอาท์พุท:

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

ผลลัพธ์แสดงว่า html5lib ไม่ได้แก้ไขปัญหาในกรณีนี้

person jfs    schedule 12.03.2009

ลองใช้ lxml (และโมดูล html ของมัน) แม้จะมีชื่อ แต่ก็ยังใช้สำหรับแยกวิเคราะห์และคัดลอก HTML อีกด้วย มันเร็วกว่า BeautifulSoup มาก และยังจัดการ HTML ที่ "เสียหาย" ได้ดีกว่า BeautifulSoup อีกด้วย มี API ความเข้ากันได้สำหรับ BeautifulSoup เช่นกัน หากคุณไม่ต้องการเรียนรู้ lxml API

เอียน บลิคกิ้งเห็นด้วย

ไม่มีเหตุผลที่จะใช้ BeautifulSoup อีกต่อไป เว้นแต่คุณจะใช้ Google App Engine หรือบางอย่างที่ไม่อนุญาตให้ใช้ Python ล้วนๆ

person aehlke    schedule 03.08.2009