2013-02-02 33 views
2

我想解析一個很奇怪的頁面。這裏有一個簡化版本:解析奇怪的網頁 - 多個html標籤

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <form id="x" method="post" action="x"> 
     <input type="hidden" name="v1" value="v" /> 
      <html xmlns="http://www.w3.org/1999/xhtml"> 
       <input type="hidden" name="v2" value="v" /> 
      </html> 
    </form> 
</html> 

是的,表單裏面有一個html標籤。

這是有效的(X)HTML嗎?我知道這是(至少部分)使用Java Server Faces完成的。

至於實際的問題:

>>> BeautifulSoup(html).find("form") 
<form id="x" method="post" action="x"> 
<input type="hidden" name="v1" value="v" /> 
</form> 

BeautifulSoup不喜歡這個在所有的,只是假裝它不存在。

有沒有人經歷過類似的事情? 我想我可能解析原始的XML,但我想使用BeautifulSoup,如果可能的話。

+0

你真的期望或需要嵌套''標籤?我會認爲理想的行爲是像BeautifulSoup那樣優雅地忽略無效標籤。 –

+0

@ m.brindley是的,我需要v2,因爲瀏覽器實際上是在表單中發送它。在這種情況下,BeautifulSoup的行爲確實很優雅,但在這種特殊情況下並不是非常有用 – goncalopp

+0

糟糕,我誤讀了您的BS輸出。我沒有意識到它已經丟棄了第二個輸入元素以及額外的''標籤。我似乎記得使用'DOCTYPE html'時有一些嚴格的規則 - 也許如果你嘗試在4.01 Transitional中使用BS,它的行爲會有所不同。 –

回答

3

我見過這種情況發生時,多個服務器來源合併而不檢查輸出。我並不認爲html標籤在文檔中間有效(不是在iframe標籤中)。您發佈的代碼段無效(validator.w3.org)

如果惡意標籤出現在可預測的位置,則字符串替換是一個快速解決方案,以便您可以隨後正確解析它。

我想我可以解析原始XML

假設文件符合其XHTML DOCTYPE良構(意思是,它是有效的XML即使不是有效的XHTML),你可以:

  • 解析文檔作爲XML
  • 修改標記的東西有效(例如解包內的元件,或者其改變爲div
  • 用BeautifulSoup解析爲HTML。
+2

這個特定的網頁更新頻率很高,所以替換字符串可能太脆弱了。將修剪後的xml傳回BeautifulSoup是一個簡單而且可能有效的想法,但我沒有想到,感謝提示! – goncalopp

0

萬一有人需要這個,我結束了編碼的動態字符串替換(如我的評論中提到,我不能簡單地削減固定位置)

def fix_html_inside_html(html): 
    i=html.index("<html") 
    while True: 
     try: 
      i=html.index("<html", i+1) 
      i2= html.index(">", i) 
      i3= html.index("</html>", i) 
      html= html[:i]+html[i2+1:i3]+html[i3+7:] 
     except ValueError: 
      break 
    return html 

注意這個失敗,如果有一個「>」內的HTML屬性