17010


こちらのページを解析したく  
<http://www.monex.co.jp/DealInfo/00000000/sinyo/meig/kiseiichiran/hyji?mop=>

[code]

    url = 'http://www.monex.co.jp/DealInfo/00000000/sinyo/meig/kiseiichiran/hyji?mop='
    doc = Nokogiri::HTML(open(url, 'r:CP932'))
    doc.to_html(encoding: 'cp932')
    
[/code]

とすると以下のエラーになってしまいます。

[code]

    encoding error : output conversion failed due to conv error, bytes 0x97 0x70 0xC2 0x83
    
[/code]

encodingを`shift_jis`にしても結果は同じですし、`to_html`に引数をつけないと`unknown encoding name -
x-sjis`のエラーになってしまいました。

どうエンコーディング処理の指定をするのが正しいのでしょうか？


CC BY-SA 3.0
2015-09-26T16:59:58.350
16970
2015-09-29T04:37:36.583
3271
question
ruby nokogiri
Nokogiri::HTML#to_htmlのエンコーディング処理で失敗する


こちらの環境は以下の通りです。

  * Ruby 2.1.2
  * Nokogiri 1.6.3

エンコーディングは対象のウェブページから取得してしまえば良いのではないでしょうか。以下のコードではエラーメッセージは表示されずに正常終了します。

[code]

    require 'open-uri'
    require 'nokogiri'
    
    url = 'http://www.monex.co.jp/DealInfo/00000000/sinyo/meig/kiseiichiran/hyji?mop='
    
    charset = nil
    doc = Nokogiri::HTML(
      open(url) do |f|
        charset = f.charset
        f.read
      end
    )
    
    puts doc.to_html(encoding: charset).to_s
    
[/code]


CC BY-SA 3.0
2015-09-26T17:33:00.123
16973
2015-09-26T17:33:00.123
16970
answer


`Nokogiri::HTML`は第一引数が`#encoding`に反応すればそれを利用し、反応しない場合ソースのmetaヘッダ等から類推しようとします。

[code]

    source = open(url).read
    source.encoding #=> #<Encoding:Shift_JIS>
    Nokogiri::HTML(source).encoding #=> 'Shift_JIS'
    # したがって
    Nokogiri::HTML(open(url).read).encoding #=> 'Shift_JIS'
    
    #一方で
    f = open(url)
    f.encoding #=> NoMethodError
    Nokogiri::HTML(open(url)).encoding #=> 'x-sjis'  (metaヘッダに由来)
    
[/code]

今回のようにmetaヘッダからの推測では不都合がある場合など、文字エンコーディングを明示的に指定する場合は第三引数で設定します。

[code]

    Nokogiri::HTML(open(url), nil, 'Shift_JIS').encoding # => 'Shift_JIS'
    
[/code]

問題はパーサに不適切なエンコーディングが指定されてしまっていることです。`#to_html`に渡すエンコーディングは出力時のものなので、ここに何を指定するかは問題とは無関係です。


CC BY-SA 3.0
2015-09-28T00:42:46.297
17010
2015-09-29T04:37:36.583
2015-09-29T04:37:36.583
5793
5793
16970
answer