¿Cómo convertir una respuesta Net :: HTTP a una cierta encoding en Ruby 1.9.1?

Tengo una aplicación de Sinatra ( http://analyzethis.espace-technologies.com ) que hace lo siguiente

  1. Recuperar una página HTML (a través de net / http)
  2. Crea un documento Nokogiri a partir de la respuesta. Cuerpo
  3. Extraiga alguna información y envíela de vuelta en la respuesta. La respuesta debe estar codificada en UTF-8.

Así que llegué al problema al intentar leer sitios que utilizan codificaciones de Windows-1256 como www.filfan.com o www.masrawy.com.

El problema es que el resultado de la conversión de encoding no es correcto, aunque no se producen errores.

La red / http response.body.encoding proporciona ASCII-8BIT que no se puede convertir a UTF-8

Si hago Nokogiri :: HTML (response.body) y uso los selectores css para obtener cierto contenido de la página, digamos el contenido de la etiqueta del título, por ejemplo, obtengo una cadena que cuando llamo string.encoding devuelve WINDOWS-1256 . Uso string.encode (“utf-8”) y envío la respuesta usando eso, pero nuevamente la respuesta no es correcta.

¿Alguna sugerencia o idea sobre lo que está mal en mi enfoque?

Porque Net :: HTTP no maneja la encoding correctamente. Ver http://bugs.ruby-lang.org/issues/2567

Puede analizar la response['content-type'] que contiene el conjunto de caracteres en lugar de analizar la response.body completa.body.

Luego use force_encoding() para establecer la encoding correcta.

response.body.force_encoding("UTF-8") si el sitio se sirve en UTF-8.

Encontré el siguiente código trabajando para mí ahora

 def document if @document.nil? && response @document = if document_encoding Nokogiri::HTML(response.body.force_encoding(document_encoding).encode('utf-8'),nil, 'utf-8') else Nokogiri::HTML(response.body) end end @document end def document_encoding return @document_encoding if @document_encoding response.type_params.each_pair do |k,v| @document_encoding = v.upcase if k =~ /charset/i end unless @document_encoding #document.css("meta[http-equiv=Content-Type]").each do |n| # attr = n.get_attribute("content") # @document_encoding = attr.slice(/charset=[a-z1-9\-_]+/i).split("=")[1].upcase if attr #end @document_encoding = response.body =~ /]*HTTP-EQUIV=["']Content-Type["'][^>]*content=["'](.*)["']/i && $1 =~ /charset=(.+)/i && $1.upcase end @document_encoding end