web-dev-qa-db-ja.com

Nokogiri、open-uri、およびUnicode文字

Nokogiriとopen-uriを使用してWebページのタイトルタグのコンテンツを取得していますが、アクセント付きの文字に問題があります。これらに対処するための最良の方法は何ですか?これが私がしていることです:

require 'open-uri'
require 'nokogiri'

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

この時点で、タイトルは次のようになります。

ラグ\ 303\271

の代わりに:

ラグー

Nokogiriに適切な文字(この場合はùなど)を返すにはどうすればよいですか?

URLの例を次に示します。

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

25
Moe

「こんな感じ」と言うとき、この値IRBを見ていますか?非ASCII範囲の文字をエスケープし、文字を表すバイトシーケンスをCスタイルでエスケープします。

プットを使用して印刷すると、シェルコンソールが問題の文字列と同じエンコーディングを使用していると想定して、期待どおりに返されます(この場合、その文字に対して返された2バイトに基づいてUTF-8と思われます) 。値をテキストファイルに保存している場合、ハンドルに出力するとUTF-8シーケンスも生成されます。

UTF-8と他のエンコーディングの間で変換する必要がある場合、詳細は、Ruby 1.9または1.8.6のどちらにいるかによって異なります。

1.9の場合: http://blog.grayproductions.net/articles/Ruby_19s_string 1.8の場合、おそらくIconvを確認する必要があります。

また、WindowsでCOMコンポーネントを操作する必要がある場合は、Rubyに、次のような正しいエンコーディングを使用するように指示する必要があります。

require 'win32ole'

WIN32OLE.codepage = WIN32OLE::CP_UTF8

Mysqlを操作している場合は、テーブルの照合順序を、使用しているエンコーディングをサポートする照合順序に設定する必要があります。一般に、コンテンツの一部が他のエンコーディングで返される場合でも、照合順序をUTF-8に設定するのが最善です。必要に応じて変換する必要があります。

Nokogiriには(おそらくIconvを介して)さまざまなエンコーディングを処理するためのいくつかの機能がありますが、私はそれについて少し慣れていないので、他の誰かに説明を任せます。

11
JasonTrue

Summary: Open-uriを介してUTF-8をNokogiriにフィードする場合は、open(...).readを使用して、結果の文字列をNokogiriに渡します。

分析: curlを使用してページをフェッチすると、ヘッダーにContent-Type: text/html; charset=UTF-8が正しく表示され、ファイルの内容に有効なUTF-8が含まれます。 "Genealogía de Jesucristo"。しかし、Rubyファイルに魔法のコメントを付けてドキュメントエンコーディングを設定しても、それは良くありません。

# 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

これはopen-uriのせいではないことがわかります。

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

これはopen-uriを扱うときののこぎりの問題のようです。これは、HTMLを生の文字列として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
61
Phrogz

私は同じ問題を抱えていて、Iconvアプローチは機能していませんでした。 _Nokogiri::HTML_はNokogiri::HTML.parse(thing, url, encoding, options)のエイリアスです。

だから、あなたはただする必要があります:

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

そしてそれはページエンコーディングを適切にutf-8に変換します。 _Ragù_の代わりに_Rag\303\271_が表示されます。

36
user660745

次のように、Nokogiriのエンコードオプションを設定してみてください。

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

スクレイピングされているWebサイト(ここではepicurious.com)からの応答をutf-8エンコーディングに変換する必要があります。

削られているページのhtmlコンテンツによると、今のところその「ISO-8859-1」。したがって、次のようなことを行う必要があります。

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

詳細については、こちらをご覧ください: http://www.quarkruby.com/2009/9/22/Rails-utf-8-and-html-screen-scraping

1
Nakul
0
the Tin Man

Nokogiri :: [〜#〜] html [〜#〜](...)をNokogiri :: HTML5(...)に変更すると、問題が修正されました特定の特殊文字、特に全角ダッシュを解析します。

(リンク内のアクセント付き文字はどちらも問題なく使用できたので、これが役立つかどうかはわかりません。)

例:

url = 'https://www.youtube.com/watch?v=4r6gr7uytQA'

doc = Nokogiri::HTML(open(url))
doc.title
=> "Josh Waitzkin â\u0080\u0094 How to Cram 2 Months of Learning into 1 Day | The Tim Ferriss Show - YouTube"

doc = Nokogiri::HTML5(open(url))
doc.title
=> "Josh Waitzkin — How to Cram 2 Months of Learning into 1 Day | The Tim Ferriss Show - YouTube"
0
Yarin

ヒント:Scrapifier gemを使用して、非常に簡単な方法でURIからページタイトルとしてメタデータを取得することもできます。データはすべてUTF-8でエンコードされています。

チェックしてください: https://github.com/tiagopog/scrapifier

お役に立てば幸いです。

0
Tiago G.