2015-09-15 42 views
2

我很難獲取網站生成的HTML。 HTML包含一些未關閉的標籤。如何使用Nokogiri正確修復未封閉的HTML標記

例如:

<div> 
    <li> 
    <div> 
     <div> 
     test 
     </div> 

    <li> 
    <div> 
     test 
    </div> 

解析HTML:

html = Nokogiri::HTML(open('origin.html')) 

結果:

Nokogiri object

或者,在HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 

    <html><body> 
     <div> 

     <li> 
      <div> 
      <div> 
       test 
      </div> 

     <li> 
      <div> 
      test 
      </div> 

    </li> 
    </div> 
    </li> 
    </div> 
    </body> 
    </html> 

我認爲正確的事情會是這樣的:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html> 
    <body> 
    <div> 
     <li> 
     <div> 
      <div> 
      test 
      </div> 
     </div> 
     </li> 

     <li> 
     <div> 
      test 
     </div> 
     </li> 
    </div> 
    </body> 
</html> 

不知道如何解決這個問題?換成另一個寶石?使用正則表達式在解析之前更改HTML?

+1

請正確縮進代碼塊,很難看到每個標籤關閉的位置。 –

+0

@AlexeyShein完成了!謝謝! –

+1

而不是使用圖像來演示數據或代碼問題,將文本複製並粘貼到問題中,並將其正確格式化以提高可讀性。這有助於我們爲您提供幫助,因爲我們可以重複使用這些數據,而無需輸入數據。 –

回答

4

你可以看看使用Nokogumbo其中Googles’ Gumbo HTML5 parser附加到Nokogiri。然後,這將在解析格式錯誤的HTML時使用HTML5錯誤更正算法,而不是執行我的Nokogiri和libxml的默認解析,並且會導致解析的HTML更接近您期望從瀏覽器中看到的內容。

下面是一個示例irb會話,顯示它如何處理您的示例HTML並生成您之後的結果。請注意,方法名稱爲HTML5,並且它仍在Nokogiri模塊上調用。

>> require 'nokogumbo' 
=> true 
>> s = <<EOT 
<div> 
    <li> 
    <div> 
     <div> 
     test 
     </div> 

    <li> 
    <div> 
     test 
    </div> 
EOT 
=> "<div>\n <li>\n <div>\n  <div>\n  test\n  </div>\n\n <li>\n  <div>\n  test \n  </div>\n" 
>> puts Nokogiri.HTML5(s).to_html 
<html> 
<head></head> 
<body><div> 
    <li> 
    <div> 
     <div> 
     test 
     </div> 

    </div> 
</li> 
<li> 
    <div> 
     test 
    </div> 
</li> 
</div></body> 
</html> 
=> nil 
+0

太棒了!工作很好!謝謝! –

0

您認爲您的<li>不應嵌套?讓我們試着去理解爲什麼Nokogiri解析這樣說:

<div> 
    <li> 
    <div> <!-- unclosed div --> 
     <div> 
     test 
     </div>  
     <li> 
     <div> 
      test 
     </div> 

首先,你的HTML是無效的,因爲(除了缺少結束標記)沒有<ul><ol>標籤,所以引入nokogiri切換到猜測向右走,從第一<li>標籤。

接下來,讓我們來看看關於結束標籤省略規格:<li>may omit它的結束標記,但<div>may not omit它。

你嵌套<li>標籤都有效的方式,引入nokogiri試圖找到第二<div>的結束標記(見上面的代碼列出HTML註釋),並選擇兩害取其輕,雖然沒有嵌套<ul>標籤。

0

如何修復未終止/未關閉的標籤取決於您的目標是什麼。 @ Matt的建議聽起來很不錯,但是如果原始HTML在病態上是錯誤的,它仍然可能導致錯誤的HTML,並且在此之前,您必須先介入並進行修復,然後再讓其他解析器試圖理解它。

是否需要使用正則表達式或簡單的字符串操作或提取特定行並將其解析爲片段取決於具體情況。我不得不做一些非常醜陋的事情,只是爲了能夠多次使用壞破壞的HTML的解析器,並且每次都是一個不同的過程。

相關問題