nokogiriがファイルの最後までパースしてくれなかった件

RubyでXpath/CSS3 selectorを使ってパースするときの選択肢のひとつ。
スクレイピングする必要がありインストールしたのですが、使えるようになるまで地味にハマったのでメモ。

http://nokogiri.org/

普通にインストールして、試してみようかと思った矢先。

[ruby]
require ‘open-uri’ require ‘nokogiri’

doc = Nokogiri::HTML(open(“http://serima.co”))
p doc
ac = doc.xpath(“//a”)
puts ac.size
[/ruby]
* こんな感じでnokogiri.rbを作成

[shell]
% ruby nokogiri.rb
#]>
0
[/shell]

なんかおかしい…1行目しか取得できてないよ…
なにがおかしいのか…と色々調べていると、こんなページを発見。

CentOS 5.5にNokogiriをインストールしたらうまくパースできなかったという話

症状が似ている。どうやらlibxml2のバージョンが古いとダメらしい。
ということで、さらに調べてみると

公式のinstallationのページにたどり着く。
http://nokogiri.org/tutorials/installing_nokogiri.html

CentOS 5 (and RHEL5) come installed with libxml 2.6.26 which, while not as offensively out-of-date as Mac Leopard, is still pretty damn old (released June 2006) and has known issues.

If you’re affected by any known bugs or are seeing odd behavior, you may want to consider uninstalling the RPMs for libxml2 and libxslt, and building them from source.

えっ

[shell]
% nokogiri -v
# Nokogiri (1.5.2)

warnings: []

nokogiri: 1.5.2
ruby:
version: 1.9.2
platform: x86_64-linux
description: ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
engine: ruby
libxml:
binding: extension
compiled: 2.6.26
loaded: 2.6.26
[/shell]

見事にlibxmlのバージョンが2.6.26ですね。
最初に気づくべきでしたが、まぁ今気付けただけでもよしとしましょう。

先ほどのブログ記事の方は、アップデートによる影響が怖いということでnokogiriのみ新しいバージョンのlibxmlを参照するようにするということだったので、それにならいます。

[shell]
# cd /usr/local/src
# wget http://xmlsoft.org/source/libxml2/libxml2-2.7.8.tar.gz
# tar xvzf libxml2-2.7.8.tar.gz
# cd libxml2-2.7.8
# ./configure –prefix=/usr/local/libxml2
# make
# make install
[/shell]

ここまでやったところで、もう一度確認。
[shell]
% nokogiri -v
WARNING: Nokogiri was built against LibXML version 2.6.26, but has dynamically loaded 2.7.8
# Nokogiri (1.5.2)

warnings:
– Nokogiri was built against LibXML version 2.6.26, but has dynamically loaded 2.7.8
nokogiri: 1.5.2
ruby:
version: 1.9.2
platform: x86_64-linux
description: ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
engine: ruby
libxml:
binding: extension
compiled: 2.6.26
loaded: 2.7.8
[/shell]

あれ、compiledとloadedのversionが違う。
例のブログ記事によると、libxsltもインストールしないとダメなケースもあるらしい。

ので、入れる。

[shell]
# cd /usr/local/src
# wget http://xmlsoft.org/source/libxslt-1.1.26.tar.gz
# tar xvzf libxslt-1.1.26.tar.gz
# cd libxslt-1.1.26
# ./configure –prefix=/usr/local/libxslt –with-libxml-prefix=/usr/local/libxml2
# make
# make install
[/shell]

[shell]
% nokogiri -v
# Nokogiri (1.5.2)

warnings: []

nokogiri: 1.5.2
ruby:
version: 1.9.2
platform: x86_64-linux
description: ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]
engine: ruby
libxml:
binding: extension
compiled: 2.7.8
loaded: 2.7.8
[/shell]

おお、無事にできた。
これで、最初に書いたサンプルスクリプトを走らせてみる。

[shell]
% ruby nokogiri.rb
#, #, #]>, #]>]>, #, #, #] children=[#] children=[#, #]>, #, #]>, #, #, #]>, #, #, #] children=[#, #] children=[#, #, #, #, #, #]>, #]>, #, #] children=[#, #]>]>, #, #] children=[#, #]>]>, #, #] children=[#, #]>]>, #, #] children=[#, #]>]>]>, #]>]>, #, #]>]>]>]>
4
[/shell]

これで、無事に全文取得できた!

#結局、libxml 2.6.26のバグが原因のようですが、installationのページの注意文言、太字とか赤字などしてもう少し目立たせてほしいなと思った次第です。
https://github.com/tenderlove/nokogiri/issues/243

高専卒→大学編入中退→起業→転職を経て、ソーシャルゲームを作ったあと、とあるアプリのサーバサイドエンジニアをやっています。 技術の未来予測とかデザインのリノベーションとか、おぎやはぎとかネギトロ丼が好きです。 猫飼いたい。 twitterは@serimaです。お気軽にfollow/unfollowどぞ(゚∀゚)

下の「いいね」ボタンを押すと、やる気パラメータが+1!


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です