当我这样做时:
require 'open-uri'
response = open('some-html-page-url-here')
response.read
在某个网址上我收到以下错误(由于返回的网址中的编码错误?!):
Encoding::UndefinedConversionError: U+00A0 from UTF-8 to US-ASCII
有什么方法可以获得html内容吗?
答案 0 :(得分:3)
在open-uri模块的介绍中,文档说这个,
可以打开http,https或ftp URL,就好像它是一个文件
如果你对阅读文件有所了解,那么你必须知道你想要阅读的文件的编码。您需要知道编码,以便告诉ruby如何读取文件(即每个字符占用多少字节(或多少空间))。
在文档的第一个代码示例中,有:
open("http://www.ruby-lang.org/en") {|f|
f.each_line {|line| p line}
p f.base_uri # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/>
p f.content_type # "text/html"
p f.charset # "iso-8859-1"
p f.content_encoding # []
p f.last_modified # Thu Dec 05 02:45:02 UTC 2002
}
因此,如果您不知道您尝试阅读的“文件”的编码,则可以使用f.charset
获取编码。如果该编码与您的default external encoding
不同,则很可能会出错。您的default external encoding
是ruby用于从外部源读取的编码。您可以检查您的默认外部编码设置如下:
从您的环境中提取默认的外部编码...有一个 看:
$ echo $LC_CTYPE
en_US.UTF-8
或
$ ruby -e 'puts Encoding.default_external.name'
UTF-8
http://graysoftinc.com/character-encodings/ruby-19s-three-default-encodings
在Mac OSX上,我实际上必须执行以下操作才能看到默认的外部编码:
$ echo $LANG
您可以使用Encoding.default_external=()
方法设置默认外部编码,因此您可能需要尝试以下方法:
open('some_url_here') do |f|
Encoding.default_external = f.charset
html = f.read
end
将IO对象设置为binmode,就像你所做的那样,告诉ruby文件的编码是BINARY(或ruby令人困惑的同义词ASCII-8BIT),这意味着你告诉ruby文件中的每个字符占用一个字节。在你的情况下,你告诉ruby读取字符U + 00A0,其UTF-8表示占用两个字节0xC2 0xA0
,作为两个字符而不是一个字符,所以你已经消除了你的错误,但你有产生了两个垃圾字符而不是原始字符。
答案 1 :(得分:2)
在response.binmode
停止发生错误之前执行response.read
。
答案 2 :(得分:1)
如果出现同样的问题,请在此处添加我的解决方案:
在进一步阅读open-uri文档之后,事实证明你可以在使用set_encoding
方法阅读之前设置io的编码,如下所示:
result = open('some-page-uri') do |io|
io.set_encoding(Encoding.default_external)
io.read
end
希望它有所帮助!