7

iso-8859-1 でエンコードされていると主張する Web ページを読むために open-uri を使用しています。ページのコンテンツを読み取ると、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>] 

これは、Web ページに有効な iso-8859 文字ではないバイト (または文字) \x92 があるためだと推測しています。http://en.wikipedia.org/wiki/ISO/IEC_8859-1 .

Web ページを utf-8 でエンコードされたファイルとして保存する必要があります。エンコーディングが正しくない Web ページの処理方法に関するアイデア。例外をキャッチして正しいエンコーディングを推測することもできますが、それは面倒でエラーが発生しやすいようです。

4

1 に答える 1

9
  • ASCII-8BIT is an alias for BINARY
  • open-uri面白いことをします: ファイルが 10kb 未満 (またはそのようなもの) の場合は aStringを返し、それより大きい場合は を返します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)

私はかなり満足しています ... http://data.brighterplanet.comensure-encodingで本番環境で使用しています

:invalid_characters => :ignoreの代わりに言うこともできます:transcode

また、何らかの形でエンコーディングがわかっている場合は、:external_encoding => 'ISO-8859-1'代わりに渡すことができます:sniff

于 2011-06-23T14:26:52.413 に答える