瞭解像引入nokogiri分析器是如何工作是很重要的。
爲了幫助你,它試圖修復損壞/格式錯誤的HTML或XML。你的HTML格式不正確,所以Nokogiri會解析它,但是,這個過程會讓Nokogiri進一步破壞HTML。爲避免這種情況,我們有時必須在將內容交給Nokogiri之前對其進行預處理,否則我們必須通過替換節點來解開它。
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<p> Hello World, ""How are you today""
<a href=""www.hello.comm"">Hello</a>
etc.
</p>
EOT
將HTML解析爲DOM。
doc.at('p').to_html
# => "<p> Hello World, \"\"How are you today\"\"\n<a href=\"\" www.hello.comm>Hello</a>\netc.\n</p>"
文本""How are you today""
未經任何忙玲處理,因爲它是一個文本節點:
doc.at('p').child.class # => Nokogiri::XML::Text
doc.at('p').child.content # => " Hello World, \"\"How are you today\"\"\n"
這是很容易固定解析後:
doc.at('p').child.content = doc.at('p').child.content.gsub('""', '"')
# => " Hello World, \"How are you today\"\n"
試圖修復<a>
標籤的參數是一個完全不同的故事,因爲在那一點上,Nokogiri已經修復了雙引號,導致標記錯誤:
doc.at('a').to_html
# => "<a href=\"\" www.hello.comm>Hello</a>"
請注意,www.hello.comm
已在其包含引號之外進行推廣。
爲了解決這個問題,需要一些預處理,然後將交給Nokogiri,或者修復節點並用固定節點替換損壞的節點。
下面是預處理<a>
標籤的基礎:
html = <<EOT
<p> Hello World, ""How are you today""
<a href=""www.hello.comm"">Hello</a>
etc.
</p>
EOT
html.gsub(/href=""([^"]+)""/, 'href="\1"')
# => "<p> Hello World, \"\"How are you today\"\"\n<a href=\"www.hello.comm\">Hello</a>\netc.\n</p>\n"
如果你走這條路,不要花哨。編寫小的原子更改,以避免在HTML更改時出現模式中斷。
更健壯的方式(其中,「穩健」是略小於我們通常開始使用分析器)是:
bad_a = doc.at('a')
fixed_a = bad_a.to_html.gsub(/""\s([^>]+)>/, '"\1">')
bad_a.replace(fixed_a)
doc.at('p')
# => #(Element:0x3fe4ce9de9e4 {
# name = "p",
# children = [
# #(Text " Hello World, \"How are you today\"\n"),
# #(Element:0x3fe4ce9e0fdc {
# name = "a",
# attributes = [
# #(Attr:0x3fe4ce9e0fa0 {
# name = "href",
# value = "www.hello.comm"
# })],
# children = [ #(Text "Hello")]
# }),
# #(Text "\netc.\n")]
# })
doc.at('p').to_html
# => "<p> Hello World, \"How are you today\"\n<a href=\"www.hello.comm\">Hello</a>\netc.\n</p>"
它可以使用毯子gsub
按摩文字,但是這有在大型/複雜文件中造成附帶損害的高風險。想象一下,當有含空字符串像許多標籤會發生什麼樣的文件,如果使用
html.gsub('""', '"')
:
<input value="" name="foo"><input value="" name="bar">
搜索結果/替換將是:
<input value=" name="foo"><input value=" name="bar">
這幾乎不能改善事情,反而會讓文件更加糟糕。
相反,最好通過手術解決問題。回到網絡黑暗,早期和開拓者的日子,我們曾經看到大量畸形的內容,並且必須使用正則表達式處理它纔是正常的攻擊計劃。現在,通過解析器,我們通常可以避免它,並可以隔離問題並有選擇地修復我們想要的內容。看看這樣做的代碼表明,做正確的事情並不需要很多。
除了一個非常簡單的例子,這在任何HTML文檔中都是一個非常糟糕的主意。 「'? –