Caractères Nokogiri, open-uri et Unicode
j'utilise Nokogiri et open-uri pour saisir le contenu de la balise titre sur une page Web, mais j'ai des problèmes avec les caractères accentués. Quelle est la meilleure façon de gérer ça? Voilà ce que je fais:
require 'open-uri'
require 'nokogiri'
doc = Nokogiri::HTML(open(link))
title = doc.at_css("title")
À ce point, le titre ressemble à ceci:
Rag303271
au lieu de:
Ragù
How puis-je avoir nokogiri retourner le caractère approprié (par exemple ù dans ce cas)?
voici un exemple D'URL:
http://www.epicurious.com/recipes/food/views/Tagliatelle-with-Duck-Ragu-242037
7 réponses
quand vous dites "ressemble à ceci", est-ce que vous voyez cette valeur IRB? Il va échapper des caractères non-ASCII gamme avec le C-Style échapper des séquences byte qui représentent les caractères.
si vous les imprimez avec des puts, vous les récupérerez comme prévu, présumant que votre console shell utilise le même encodage que la chaîne en question (apparemment UTF-8 dans ce cas, basé sur les deux octets retournés pour ce caractère). Si vous stockez les valeurs dans un fichier texte, l'impression à une poignée devrait également entraîner des séquences UTF-8.
si vous devez traduire entre UTF-8 et d'autres encodages, les détails dépendent de Si vous êtes dans Ruby 1.9 ou 1.8.6.
pour 1.9: http://blog.grayproductions.net/articles/ruby_19s_string pour 1.8, vous devez probablement regarder Iconv.
aussi, si vous avez besoin d'interagir avec des composants COM dans Windows, vous aurez besoin de dire à ruby pour utiliser le codage correct avec quelque chose comme ce qui suit:
require 'win32ole'
WIN32OLE.codepage = WIN32OLE::CP_UTF8
si vous êtes en interaction avec mysql, vous aurez besoin de mettre la collation sur la table à un qui supporte l'encodage que vous travaillez avec. En général, il est préférable de régler la collation à UTF-8, même si une partie de votre contenu est de retour dans d'autres encodages; vous aurez juste besoin de convertir si nécessaire.
Nokogiri a quelques caractéristiques pour faire face aux différents encodages (probablement par Iconv), mais je suis un peu hors de pratique avec ça, donc je vais laisser l'explication de cela à quelqu'un d'autre.
résumé: lorsque vous donnez de L'UTF-8 à Nokogiri par l'intermédiaire d'un uri ouvert, utilisez open(...).read
et passez la chaîne résultante à Nokogiri.
analyse:
Si je récupère la page en utilisant curl, les en-têtes montrent correctement Content-Type: text/html; charset=UTF-8
et le contenu du fichier inclut UTF-8 valide, par exemple "Genealogía de Jesucristo"
. Mais même avec un commentaire magique sur le fichier Ruby et la mise en place de l'encodage doc, ce n'est pas bon:
# 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
nous pouvons voir que ce n'est pas la faute de l'uri ouvert:
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
C'est une question de Nokogiri quand il s'agit d'uri ouverte, semble-t-il. Cela peut être contourné en passant le HTML comme chaîne brute à 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
j'avais le même problème et L'approche Iconv ne fonctionnait pas. Nokogiri::HTML
est un alias de Nokogiri::HTML.parse(thing, url, encoding, options)
.
Donc, vous avez juste besoin de faire:
doc = Nokogiri::HTML(open(link).read, nil, 'utf-8')
et il convertira le codage de page correctement en utf-8. Vous verrez Ragù
au lieu de Rag31
.
essayez de définir L'option d'encodage de Nokogiri, comme ceci:
require 'open-uri'
require 'nokogiri'
doc = Nokogiri::HTML(open(link))
doc.encoding = 'utf-8'
title = doc.at_css("title")
vous devez convertir la réponse du site web étant raclée (ici epicurious.com) dans l'encodage utf-8.
selon le contenu html de la page en cours de grattage, son" ISO-8859-1 " pour le moment. Donc, vous devez faire quelque chose comme ceci:
require 'iconv'
doc = Nokogiri::HTML(Iconv.conv('utf-8//IGNORE', 'ISO-8859-1', open(link).read))
plus d'informations ici: http://www.quarkruby.com/2009/9/22/rails-utf-8-and-html-screen-scraping
juste pour ajouter un renvoi, cette page SO donne quelques informations connexes:
astuce: vous pouvez également utiliser le Scrapifier gem pour obtenir des métadonnées, comme le titre de la page, à partir D'URIs d'une manière très simple. Les données sont toutes codées en UTF-8.
Check it out: https://github.com/tiagopog/scrapifier
J'espère que c'est utile pour vous.