Nokogiri,open-uri和Unicode角色

我正在使用Nokogiri和open-uri来抓取网页上标题标签的内容,但是在重音字符方面遇到了麻烦。 处理这些问题的最佳方法是什么? 这就是我正在做的事情:

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

此时,标题看起来像这样:

抹布\ 303 \ 271

代替:

肉酱

我怎样才能让nokogiri返回正确的字符(例如,在这种情况下为ù)?

这是一个示例url:

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

当你说“看起来像这样”时,你是否正在查看这个值IRB? 它将通过C样式转义表示字符的字节序列来转义非ASCII范围字符。

如果你使用puts打印它们,你会按照你的预期将它们取回,假设你的shell控制台使用与相关字符串相同的编码(在这种情况下显然是UTF-8,基于该字符返回的两个字节) 。 如果要将值存储在文本文件中,则打印到句柄也应该生成UTF-8序列。

如果您需要在UTF-8和其他编码之间进行转换,具体取决于您是使用Ruby 1.9还是1.8.6。

对于1.9: http : //blog.grayproductions.net/articles/ruby_19s_string for 1.8,您可能需要查看Iconv。

此外,如果您需要与Windows中的COM组件进行交互,则需要告诉ruby使用正确的编码,如下所示:

 require 'win32ole' WIN32OLE.codepage = WIN32OLE::CP_UTF8 

如果您正在与mysql交互,则需要将表上的排序规则设置为支持您正在使用的编码的排序规则。 一般情况下,最好将排序规则设置为UTF-8,即使您的某些内容以其他编码方式返回; 你只需要根据需要进行转换。

Nokogiri有一些处理不同编码的function(可能是通过Iconv),但是我有点不习惯,所以我会把这个解释给别人。

简介:当通过open-uri向UTok-8提供UTF-8时,请使用open(...).read并将生成的字符串传递给Nokogiri。

分析:如果我使用curl获取页面,则标题正确显示Content-Type: text/html; charset=UTF-8 Content-Type: text/html; charset=UTF-8 ,文件内容包括有效的UTF-8,例如"Genealogía de Jesucristo" 。 但即使对Ruby文件进行了神奇的评论并设置了doc编码,它也没有用:

 # 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 

我们可以看到这不是open-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 

我遇到了同样的问题而且Iconv方法无效。 Nokogiri::HTMLNokogiri::HTML.parse(thing, url, encoding, options)的别名。

所以,你只需要这样做:

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

它会将页面编码正确转换为utf-8。 你会看到Ragù而不是Rag\303\271

尝试设置Nokogiri的编码选项,如下所示:

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

您需要将被抓取的网站(此处为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

只是为了添加交叉引用,这个SO页面提供了一些相关信息:

如何使Nokogiri透明地返回未编码的Html实体?

提示:您还可以使用Scrapifier gem以非常简单的方式从URI获取元数据作为页面标题。 数据全部以UTF-8编码。

看看: https : //github.com/tiagopog/scrapifier

希望它对你有用。