Iconv :: IllegalSequence cuando se utiliza www :: mecanizar
-
06-09-2019 - |
Pregunta
Estoy tratando de hacer un poco de web scraping, pero la WWW: no parece Mecanice joya para recibir la codificación y accidentes
.
Los resultados petición POST en una redirección 302 (que sigue mecanizar, hasta ahora tan bueno) y la página resultante suele bloquearse ella.
Busqué en Google un poco, pero nada ocurrió hasta ahora la forma de resolver esto. Cualquiera de ustedes tiene una idea?
Código:
require 'rubygems'
require 'mechanize'
agent = WWW::Mechanize.new
agent.user_agent_alias = 'Mac Safari'
answer = agent.post('https://www.budget.de/de/reservierung/privatkunden/step1/schnellbuchung',
{"Country" => "Deutschland",
"Abholstation" => "Aalen",
"Abgabestation" => "Aalen",
"Abholdatum" => "26.02.2009",
"Abholzeit_stunde" => "13",
"Abholzeit_minute" => "30",
"Abgabedatum" => "28.02.2009",
"Abgabezeit_stunde" => "13",
"Abgabezeit_minute" => "30",
"CountryID" => "DE",
"AbholstationID"=>"AA1",
"AbgabestationID"=>"AA1"
}
)
puts answer.body
Error:
D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/util.rb:29:in `iconv': "\204nderungen vorbe"... (Iconv::IllegalSequence)
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/util.rb:29:in `to_native_charset'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/chain/response_header_handler.rb:29:in `handle'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/chain.rb:30:in `pass'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/chain/handler.rb:6:in `handle'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/chain/response_body_parser.rb:35:in `handle'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/chain.rb:30:in `pass'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/chain/handler.rb:6:in `handle'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/chain/pre_connect_hook.rb:14:in `handle'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize/chain.rb:25:in `handle'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize.rb:494:in `fetch_page'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize.rb:545:in `fetch_page'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize.rb:403:in `post_form'
from D:/Ruby/lib/ruby/gems/1.8/gems/mechanize-0.9.1/lib/www/mechanize.rb:322:in `post'
from test.rb:7
Solución
Esa página es sin duda UTF-8, sin embargo Mechanize utiliza NKF (una biblioteca de Ruby núcleo) de adivinar la codificación y por alguna razón lo hará como Shift JIS. La forma más rápida para evitar el problema es reemplazar el mapeo de codificación para Mechanize, de modo que cuando se intenta convertir el cuerpo para UTF-8 usando Iconv que pasa en la codificación de fuente como UTF-8 también. Puede hacerlo de esta manera:
WWW::Mechanize::Util::CODE_DIC[:SJIS] = "UTF-8"
lugar que después de la línea en la que require
la biblioteca Mechanize. Es posible que desee establecer el valor de nuevo inmediatamente después, o mejor aún, encontrar la causa del problema y enviar un parche si es necesario.
Nota: La forma en que esto fue resuelto por la depuración de la biblioteca Mechanize mediante el uso de la traza. El método to_native_charset
llama detect_charset
que es donde estaba el problema.
Otros consejos
En mi caso un Mechanize::File
fue devuelto por el método get que no utiliza codificación en absoluto.
Yo era capaz de solucionarlo mediante la conversión de forma manual con Iconv
, pero esto sólo funciona si conoce la codificación ya.
result = @agent.get uri
# Mechanize::File instead of Mechanize::Page is returned
# so we have to convert manually
result = Iconv.conv("utf-8", "iso-8859-1", result.body)