Help us understand the problem. What is going on with this article?

CrystalによるWebスクレイピング

More than 3 years have passed since last update.

この記事はCrystal Advent Calendar 2015 22日目の記事です。
当初は@pine613さんが書く場所だったのですが、
譲っていただきました。 ありがとうございます。


というわけで今回はCrystalを使ってWebスクレイピングしたいと思います。
RubyでWebスクレイピングをする際はNokogiriという非常に使いやすいライブラリを使用するのですが
CrystalにはまだNokogiriのようなすぐれたライブラリが存在しない(と思っている)ので
今回はxpathを使用します。

コードとしてはそれほど難しいことはしていません。
Crystal Advent Calendar 2015に接続して
日付、ブログ記載者、ブログタイトルそしてブログのURLを取得するというプログラムです。

test.cr
require "xml"
require "http/client"

res = HTTP::Client.get "http://www.adventar.org/calendars/800"
xml = XML.parse_html(res.body)
# 毎日のカレンダーの情報のノードを取得
nodes = xml.xpath_nodes "//th[@class=\"mod-entryList-date\"]/parent::node()"

nodes.each{|node|
  puts "------------------"
  x = XML.parse_html(node.to_xml)
  puts x.xpath_node("//th").text # 日付
  puts x.xpath_node("//td[@class=\"mod-entryList-user\"]/a/span").text # 記者
  puts x.xpath_node("//div[@class=\"mod-entryList-title\"]").text # タイトル
  puts x.xpath_node("//div[@class=\"mod-entryList-url\"]/a")["href"] #URL
  puts "------------------"
}

ここで注意が必要なのは(当然なのだが)Crystalでxmlライブラリを使用する際は
コンパイルの際に幾つかのライブラリが必要となります。
ですので、ライブラリが存在しない場合は入れておく必要があります。

libssl
libxml2
libevent
librt
libpcl
libgc
libpthread
libdl

コンパイルするとエラーになる

上記ライブラリが存在しないとコンパイルするときにエラーになります。
エラー内容は下記のような感じ。

Error: execution of command failed with code: 1: `cc -o "/home/.../crystal-run-test.tmp" "${@}"  -rdynamic  -lssl -lxml2 -levent -lrt -lpcl -lpcre -lgc -lpthread -ldl`

libgc.aはCrystalのライブラリディレクトリ(crystal/embedded/lib)に
存在するのですが、なぜか私の環境ではパスが通っていなかったため
コンパイルエラーになっていました。
なので必要に応じてパスを通します。

CSSセレクタがほしい

やってみてわかったことですが、RubyのNokogiriはやはりかなり優れたライブラリです。
本当はCrystalでNokogiriのようなCSSセレクタを作成して
Webスクレイピングしたという記事を書きたかったのですが
今の段階でCSSセレクタを作るのが難しいので断念してしまいました。

というのも、Rubyでは標準としてRaccというLALRのパーサージェネレータが存在し、
Nokogiriでもそれを使用しています。
CrystalにはLALRパーサーがない(はずな)のでまずはそっちからかなと思っています。

冬休みの宿題

なので今年の冬休みの宿題は

  • RaccのようなLALR(1)パースジェネレータを作成する
  • NokogiriのようなCSSセレクタを作成する

では明日のCrystal Advent Calendar 2015は kmizu さんです。
よろしくお願いします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away