2010-04-03 63 views
23

我使用的是引入nokogiri和開放URI搶在網頁標題標籤的內容,但我有重音字符的麻煩。處理這些問題的最佳方法是什麼?下面是我在做什麼:引入nokogiri,開URI和Unicode字符

require 'open-uri' 
require 'nokogiri' 

doc = Nokogiri::HTML(open(link)) 
title = doc.at_css("title") 

在這一點上,標題是這樣的:

碎布\ 303 \ 271

相反的:

Ragù

如何讓nokogiri返回正確的字符(例如:在這種情況下)?

下面是一個例子網址:

http://www.epicurious.com/recipes/food/views/Tagliatelle-with-Duck-Ragu-242037

+0

如果我們能夠訪問該網站的網址,我們可以對其進行測試,對於那些願意幫助的人來說,這將會有所幫助。 – 2010-04-03 19:35:10

+0

之後你如何檢查標題以及你正在使用哪個Ruby版本? 'Rag \ 303 \ 271' _is_'Ragù'UTF-8-encoded。 – 2010-04-03 19:51:11

+0

嗨Mladen,我使用Ruby 1.8.6。我正在從Ruby交互式控制檯檢查標題。最終,它最終被存儲在MySQL數據庫中。一旦進入MySQL,它看起來像:Ã – Moe 2010-04-03 19:59:50

回答

10

當你說 「是這樣的,」 你查看此值IRB?它將轉義非字符範圍的字符,用C風格轉義表示字符的字節序列。

如果使用puts打印它們,您會按照預期將它們還原,假設您的shell控制檯正在使用與所討論的字符串相同的編碼(顯然,在這種情況下UTF-8基於返回的兩個字節爲那個角色)。如果將值存儲在文本文件中,則打印到句柄也應該導致UTF-8序列。

如果需要UTF-8和其他編碼之間進行轉換,具體取決於您是否是用Ruby 1.9或1.8.6。

For 1.9:http://blog.grayproductions.net/articles/ruby_19s_string for 1.8,你可能需要看Iconv。

另外,如果你需要在Windows COM組件進行交互,你需要告訴紅寶石使用正確的編碼,類似如下:

require 'win32ole' 

WIN32OLE.codepage = WIN32OLE::CP_UTF8 

如果你使用MySQL進行交互,您需要將表格上的排序規則設置爲支持您正在使用的編碼的排序規則。一般來說,最好將排序規則設置爲UTF-8,即使其中一些內容以其他編碼形式返回也是如此。你只需要根據需要進行轉換。

引入nokogiri有不同的編碼處理(可能是通過語言Iconv)的一些功能,但我有點出與實踐,所以我會離開這個解釋給別人。

+0

嗨傑森,非常感謝所有的幫助。得到它完美的工作。我將我的MySQL數據庫編碼設置爲UTF-8以及我的終端配置文件。 – Moe 2010-04-03 21:31:55

+0

@Moe這可能是'處理'的問題,或者它可能掩蓋了它。查看我的答案,瞭解如何確保Nokogiri獲得正確的UTF-8內容。 – Phrogz 2011-01-15 21:02:53

1

你需要轉換被刮從網站的響應(這裏epicurious.com)爲UTF-8編碼。

按照網頁中的HTML內容被刮掉,它的「ISO-8859-1」現在。所以,你需要做這樣的事情:

require 'iconv' 
doc = Nokogiri::HTML(Iconv.conv('utf-8//IGNORE', 'ISO-8859-1', open(link).read)) 

瞭解更多關於在這裏:​​http://www.quarkruby.com/2009/9/22/rails-utf-8-and-html-screen-scraping

+0

從提供的示例中,很明顯他的內容已經是UTF-8。 – JasonTrue 2010-04-08 06:22:19

+0

不是。否則他只會得到ù。該網頁不是utf-8編碼的 – Nakul 2010-04-08 13:50:52

+0

\ 303 \ 271是c-escaped UTF-8字節值,這就是它們在查看評估字符串時如何出現在IRB中;它是C3 B9的八進制數,它是ù的UTF-8序列。如果是iso-8859-1,他會得到F9的八進制數,或者\ 371。 – JasonTrue 2010-04-09 23:26:04

6

嘗試設置引入nokogiri的編碼選項,例如:

require 'open-uri' 
require 'nokogiri' 
doc = Nokogiri::HTML(open(link)) 
doc.encoding = 'utf-8' 
title = doc.at_css("title") 
56

摘要:當通過open-uri將UTF-8餵給Nokogiri時,請使用open(...).read並將生成的字符串傳遞給Nokogiri。

分析: 如果我使用curl抓取網頁,標題正確顯示Content-Type: text/html; charset=UTF-8,文件內容包括有效UTF-8,例如"Genealogía de Jesucristo"。但是,即使在Ruby文件和設置文檔編碼一個神奇的評論,它沒有好:

# encoding: UTF-8 
require 'nokogiri' 
require 'open-uri' 

doc = Nokogiri::HTML(open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI')) 
doc.encoding = 'utf-8' 
h52 = doc.css('h5')[1] 
puts h52.text, h52.text.encoding 
#=> Genealogà a de Jesucristo 
#=> UTF-8 

我們可以看到,這是不是開-URI故障:

html = open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI') 
gene = html.read[/Gene\S+/] 
puts gene, gene.encoding 
#=> Genealogía 
#=> UTF-8 

這是似乎是在處理open-uri時的一個Nokogiri問題。這可以通過將HTML作爲原始字符串引入nokogiri被工作圍繞:

# encoding: UTF-8 
require 'nokogiri' 
require 'open-uri' 

html = open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI') 
doc = Nokogiri::HTML(html.read) 
doc.encoding = 'utf-8' 
h52 = doc.css('h5')[1].text 
puts h52, h52.encoding, h52 == "Genealogía de Jesucristo" 
#=> Genealogía de Jesucristo 
#=> UTF-8 
#=> true 
+0

謝謝你再次幫助我:) – 2011-01-31 21:55:26

+0

非常感謝這個答案! – 2011-12-26 20:51:30

+1

哇,我從來不會想到加入'.read'會解決這個問題。謝謝! – g33kz0r 2015-11-04 17:47:58

36

我有同樣的問題和語言Iconv的做法是行不通的。 Nokogiri::HTMLNokogiri::HTML.parse(thing, url, encoding, options)的別名。

所以,你只需要做:

doc = Nokogiri::HTML(open(link).read, nil, 'utf-8')

,它會正確地轉換頁面編碼爲UTF-8。您將看到Ragù而不是Rag\303\271

0

提示:您也可以使用Scrapifier gem以非常簡單的方式從URI獲取元數據(作爲頁面標題)。數據全部以UTF-8編碼。

檢查出來:https://github.com/tiagopog/scrapifier

希望這對您有用。