2010-04-03 7 views
23

Estoy usando Nokogiri y open-uri para tomar el contenido de la etiqueta del título en una página web, pero estoy teniendo problemas con los caracteres acentuados. ¿Cuál es la mejor manera de lidiar con esto? Esto es lo que estoy haciendo:Nokogiri, open-uri, y caracteres Unicode

require 'open-uri' 
require 'nokogiri' 

doc = Nokogiri::HTML(open(link)) 
title = doc.at_css("title") 

En este punto, el título es el siguiente:

trapo \ 303 \ 271

En lugar de:

Ragù

¿Cómo puedo hacer que nokogiri muestre el carácter correcto (p. ù en este caso)?

He aquí un ejemplo de URL:

http://www.epicurious.com/recipes/food/views/Tagliatelle-with-Duck-Ragu-242037

+0

Sería de ayuda para aquellos que ayudan si pudiéramos tener la URL del sitio para que podamos probar en su contra. –

+0

¿Cómo se inspecciona el título después y qué versión de Ruby está usando? 'Rag \ 303 \ 271' _is_' Ragù' UTF-8-encoded. –

+0

Hola, Mladen, estoy usando Ruby 1.8.6. Estoy inspeccionando el título desde la consola interactiva de Ruby. En última instancia, termina siendo almacenado en una base de datos MySQL. Una vez en MySQL, parece que: ù – Moe

Respuesta

10

Cuando se dice "se parece a esto:" ¿Estás viendo este valor IRB? Va a escapar caracteres de rango no ASCII con escape de estilo C de las secuencias de bytes que representan los caracteres.

Si las imprime con puts, las recuperará como espera, suponiendo que su consola de shell utiliza la misma codificación que la cadena en cuestión (Aparentemente UTF-8 en este caso, en función de los dos bytes devueltos para ese personaje). Si está almacenando los valores en un archivo de texto, imprimir en un manejador también debería dar como resultado secuencias UTF-8.

Si necesita traducir entre UTF-8 y otras codificaciones, los detalles dependen de si está en Ruby 1.9 o 1.8.6.

Para 1.9: http://blog.grayproductions.net/articles/ruby_19s_string para 1.8, probablemente necesite mirar Iconv.

Además, si usted necesita para interactuar con los componentes COM en Windows, tendrá que indicar a Ruby a utilizar la codificación correcta con algo como lo siguiente:

require 'win32ole' 

WIN32OLE.codepage = WIN32OLE::CP_UTF8 

Si está interactuando con MySQL, Deberá establecer la intercalación en la tabla para que sea compatible con la codificación con la que está trabajando. En general, es mejor establecer la intercalación en UTF-8, incluso si parte de su contenido vuelve a aparecer en otras codificaciones; solo necesitarás convertir según sea necesario.

Nokogiri tiene algunas características para tratar con diferentes codificaciones (probablemente a través de Iconv), pero estoy un poco fuera de práctica con eso, así que le dejo la explicación a alguien más.

+0

Hola Jason, muchas gracias por toda la ayuda. Lo tengo funcionando perfectamente. Establecí mi codificación MySQL DB en UTF-8 y en mi perfil de terminal. – Moe

+0

@Moe Esto podría estar 'manejando' el problema, o podría estar enmascarando. Vea mi respuesta sobre cómo asegurar limpiamente que Nokogiri esté obteniendo el contenido correcto de UTF-8. – Phrogz

1

Es necesario para convertir la respuesta de la página web que se raspa (aquí epicurious.com) en UTF-8 codificación

según el contenido html de la página que se está raspando, es "ISO-8859-1" por el momento.Por lo tanto, es necesario hacer algo como esto:

require 'iconv' 
doc = Nokogiri::HTML(Iconv.conv('utf-8//IGNORE', 'ISO-8859-1', open(link).read)) 

leer mas sobre esto aquí: http://www.quarkruby.com/2009/9/22/rails-utf-8-and-html-screen-scraping

+0

De la muestra provista, está claro que su contenido ya está en UTF-8. – JasonTrue

+0

no, no lo es. de lo contrario, obtendría ù solo. la página web no está codificada en utf-8 – Nakul

+0

\ 303 \ 271 son valores de byte UTF-8 escapados de c, que es como aparecen en IRB cuando observa una cadena evaluada; es octal para C3 B9, que es la secuencia UTF-8 para ù. Si fuera iso-8859-1, habría obtenido el octal para F9, o \ 371. – JasonTrue

6

intente configurar la opción de codificación de Nokogiri, así:

require 'open-uri' 
require 'nokogiri' 
doc = Nokogiri::HTML(open(link)) 
doc.encoding = 'utf-8' 
title = doc.at_css("title") 
56

Resumen: Al alimentar UTF-8 a Nokogiri a través de open-uri, use open(...).read y pase la cadena resultante a Nokogiri.

Análisis: Si voy a buscar la página utilizando rizo, las cabeceras muestran correctamente Content-Type: text/html; charset=UTF-8 y el contenido del archivo incluye válida UTF-8, por ejemplo, "Genealogía de Jesucristo". Pero incluso con un comentario magia en el archivo de Ruby y establecer la codificación de documento, que no es bueno:

# encoding: UTF-8 
require 'nokogiri' 
require 'open-uri' 

doc = Nokogiri::HTML(open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI')) 
doc.encoding = 'utf-8' 
h52 = doc.css('h5')[1] 
puts h52.text, h52.text.encoding 
#=> Genealogà a de Jesucristo 
#=> UTF-8 

Podemos ver que esto no es culpa de-uri abierta:

html = open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI') 
gene = html.read[/Gene\S+/] 
puts gene, gene.encoding 
#=> Genealogía 
#=> UTF-8 

Este es un problema de Nokogiri cuando se trata de open-uri, parece. Esto se puede solucionar haciendo pasar el HTML como una cadena prima para Nokogiri:

# encoding: UTF-8 
require 'nokogiri' 
require 'open-uri' 

html = open('http://www.biblegateway.com/passage/?search=Mateo1-2&version=NVI') 
doc = Nokogiri::HTML(html.read) 
doc.encoding = 'utf-8' 
h52 = doc.css('h5')[1].text 
puts h52, h52.encoding, h52 == "Genealogía de Jesucristo" 
#=> Genealogía de Jesucristo 
#=> UTF-8 
#=> true 
+0

gracias me acabas de ayudar :) –

+0

¡Muchas gracias por esta respuesta! –

+1

Wow, nunca me hubiera dado cuenta de que la adición de '.read' arreglaría esto. ¡Gracias! – g33kz0r

36

que estaba teniendo el mismo problema y el enfoque Iconv no estaba funcionando. Nokogiri::HTML es un alias de Nokogiri::HTML.parse(thing, url, encoding, options).

Por lo tanto, sólo tiene que hacer:

doc = Nokogiri::HTML(open(link).read, nil, 'utf-8')

y va a convertir la codificación de página correctamente a UTF-8. Verá Ragù en lugar de Rag\303\271.

0

Sugerencia: También podría utilizar la gema Scrapifier para obtener metadatos, como el título de la página, de los URI de una manera muy simple. Todos los datos están codificados en UTF-8.

Compruébelo usted mismo: https://github.com/tiagopog/scrapifier

espero que sea útil para usted.