2010-07-16 67 views
3

我試圖用引入nokogiri解析以下段引入nokogiri:解析不規則「<」

<tr> 
<th>Total Weight</th> 
<td>< 1 g</td> 
<td style="text-align: right">0 %</td> 

</tr>    
<tr><td class="skinny_black_bar" colspan="3"></td></tr> 

不過,我認爲「<」登錄「<1克」引起引入nokogiri問題。有誰知道任何解決方法?有沒有辦法逃避「<」的標誌?或者,也許有一個函數,我可以調用只是獲得純html段?

回答

2

「小於」(<)isn't legal HTML,但瀏覽器有很多代碼來確定HTML的含義,而不是僅顯示錯誤。這就是爲什麼你的無效HTML樣本在瀏覽器中顯示你想要的樣子。

所以訣竅是確保Nokogiri做同樣的工作來彌補壞的HTML。確保解析該文件作爲HTML而不是XML的:

f = File.open("table.html") 
doc = Nokogiri::HTML(f) 

此解析您的文件只是罰款,但扔掉了< 1 g文本。怎麼看待第2種TD元素的內容解析:

doc.xpath('(//td)[1]/text()').to_s 
=> "\n " 

doc.xpath('(//td)[2]/text()').to_s 
=> "0 %" 

引入nokogiri拋出了你的無效的文本,但保留解析周圍結構。你甚至可以看到來自Nokogiri的錯誤信息:

doc.errors 
=> [#<Nokogiri::XML::SyntaxError: htmlParseStartTag: invalid element name>] 
doc.errors[0].line 
=> 3 

是的,第3行不好。

所以看起來Nokogiri沒有像瀏覽器那樣解析無效HTML的支持。我建議使用其他庫來預處理文件。我試圖運行在你的示例文件TagSoup,並通過改變它固定<&lt;像這樣:

% java -jar tagsoup-1.1.3.jar foo.html | xmllint --format - 
src: foo.html 
<?xml version="1.0" standalone="yes"?> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <body> 
    <table> 
     <tbody> 
     <tr> 
      <th colspan="1" rowspan="1">Total Weight</th> 
      <td colspan="1" rowspan="1">&lt;1 g</td> 
      <td colspan="1" rowspan="1" style="text-align: right">0 %</td> 
     </tr> 
     <tr> 
      <td colspan="3" rowspan="1" class="skinny_black_bar"/> 
     </tr> 
     </tbody> 
    </table> 
    </body> 
</html> 
+0

是否有任何Ruby包將像TagSoup一樣強大地解析HTML? – sampablokuper 2012-06-13 05:13:23

4

作爲速戰速決,我想出了使用reqular表達這種方法來確定未關閉的標籤:

def fix_irregular_html(html) 
    regexp = /<([^<>]*)(<|$)/ 

    #we need to do this multiple time as regex are overlapping 
    while (fixed_html = html.gsub(regexp, "&lt;\\1\\2")) && fixed_html != html 
    html = fixed_html 
    end 

    fixed_html 
end 

查看完整的代碼,包括測試在這裏: https://gist.github.com/796571

它工作了很適合我,我明白任何反饋和改進