【问题标题】:open-uri returning ASCII-8BIT from webpage encoded in iso-8859open-uri 从以 iso-8859 编码的网页返回 ASCII-8BIT
【发布时间】:2011-04-19 05:43:43
【问题描述】:

我正在使用 open-uri 读取一个声称以 iso-8859-1 编码的网页。当我读取页面内容时,open-uri 返回一个以 ASCII-8BIT 编码的字符串。

open("http://www.nigella.com/recipes/view/DEVILS-FOOD-CAKE-5310") {|f| p f.content_type, f.charset, f.read.encoding }
 => ["text/html", "iso-8859-1", #<Encoding:ASCII-8BIT>] 

我猜这是因为网页的字节(或字符)\x92 不是有效的 iso-8859 字符。 http://en.wikipedia.org/wiki/ISO/IEC_8859-1

我需要将网页存储为 utf-8 编码文件。关于如何处理编码不正确的网页的任何想法。我可以捕捉到异常并尝试猜测正确的编码,但这似乎很麻烦且容易出错。

【问题讨论】:

  • 你使用的是什么版本的 Ruby?
  • 我使用的是 1.9.2。是的,\x92 表示 CP1252。我正在寻找一个更通用的解决方案或关于如何在编码未知或与 html 标头不一致时解析 html 的想法
  • 也许stackoverflow.com/questions/7821853/… 会有所帮助。

标签: ruby encoding internationalization open-uri


【解决方案1】:
  • ASCII-8BIT is an alias for BINARY
  • open-uri 做了一件有趣的事:如果文件小于 10kb(或类似的东西),它返回一个 String,如果它更大,它返回一个 StringIO。如果您尝试处理编码问题,这可能会让人感到困惑。

如果文件不是很大,我建议手动将它们加载到字符串中:

require 'uri'
require 'net/http'
require 'net/https'

uri = URI.parse url_to_file

http = Net::HTTP.new(uri.host, uri.port)
if uri.scheme == 'https'
  http.use_ssl = true
  # possibly useful if you see ssl errors
  # http.verify_mode = ::OpenSSL::SSL::VERIFY_NONE
end
body = http.start { |session| session.get uri.request_uri }.body

然后你可以使用https://rubygems.org/gems/ensure-encoding gem

require 'ensure/encoding'
utf8_body = body.ensure_encoding('UTF-8', :external_encoding => :sniff, :invalid_characters => :transcode)

我对@9​​87654329@ 非常满意...我们在生产环境中使用它http://data.brighterplanet.com

请注意,您也可以说 :invalid_characters =&gt; :ignore 而不是 :transcode

另外,如果你知道编码,你可以传递:external_encoding =&gt; 'ISO-8859-1' 而不是:sniff

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-23
    相关资源
    最近更新 更多