测试regex时发生ruby 1.9字符转换错误



我知道有很多文档和争论,但仍然是:

这是我在Rails上测试各种网站抓取数据的最佳尝试。奇怪的是,如果我手动复制粘贴URL的来源,一切都会正常进行。

我能做什么?

# encoding: utf-8
require 'rubygems'
require 'iconv'
require 'nokogiri'
require 'open-uri'
require 'uri'
url = 'http://www.website.com/url/test'
sio = open(url)
@cur_encoding = sio.charset
doc = Nokogiri::HTML(sio, nil, @cur_encoding)
txtdoc = doc.to_s
# 1) String manipulation test
p doc.search('h1')[0].text # "Nove36  "
p doc.search('h1')[0].text.strip! # nil <- ERROR

# 2) Regex test
# txtdoc = "test test 44.00 € test test" # <- THIS WORKS
regex = "[0-9.]+ €"

p /#{regex}/i =~ txtdoc # integer expected

我意识到,也许我的操作系统Ubuntu加上我的文本编辑器正在进行一些很好的编码转换,而不是一些损坏的编码:这很好,但我如何在实时运行的同时在我的应用程序上解决这个问题?

@cur_encoding=doc.encoding#ISO-8859-15

ISO-8859-15不是引用页面的正确编码;它应该是UTF-8。将其图标化为UTF-8,就好像它是8859-15一样,这只会加剧问题。

此编码来自文档中有故障的<meta>标记。浏览器将忽略该标记,并使用Content-Type: text/html;charset=utf-8 HTTP响应标头中的重写编码。

然而,Nokogiri似乎无法从open() ed流中读取此标头。需要注意的是,我对Ruby一无所知,从源代码来看,问题似乎是它使用了字符串或IO中的属性encoding,而不是open-uri所写的charset

你可以传入自己的覆盖编码,所以我想试试:

sio= open(url)
doc= Nokogiri::HTML.parse(doc, nil, sio.charset) # should be UTF-8?

您遇到的问题是由页面中的非中断空格字符(Unicode U+00A0)引起的。

在你的第一个问题中,字符串:

"Nove36  "

实际上以U+00A0结尾,String#strip!不认为这个字符是要删除的空白:

1.9.3-p125 :001 > s = "Foo u00a0"
 => "Foo  " 
1.9.3-p125 :002 > s.strip
 => "Foo  "    #unchanged

在第二个问题中,价格和欧元符号之间的空间再次是一个不间断的空间,因此正则表达式根本不匹配,因为它正在寻找一个正常的空间:

# s as before
1.9.3-p125 :003 > s =~ /Foo  / #2 spaces, no match
 => nil 
1.9.3-p125 :004 > s =~ /Foo /  #1 space, match
 => 0 
1.9.3-p125 :005 > s =~ /Foo u00a0/  #space and non breaking space, match
 => 0

当您复制和粘贴源时,浏览器可能会对非打断空间进行规范化,因此您只复制正常的空间字符,这就是它以这种方式工作的原因。

最简单的修复方法是在开始处理之前对空间进行u00a0的全局替换:

sio = open(url)
@cur_encoding = sio.charset
txt = sio.read             #read the whole file
txt.gsub! "u00a0", " "    #global replace
doc = Nokogiri::HTML(txt, nil, @cur_encoding)   #use this new string instead...

相关内容

  • 没有找到相关文章

最新更新