orangain flavor

じっくりコトコト煮込んだみかん2。知らないことを知りたい。

クローラーをデーモンとして動かす ― Scrapyd

この記事はクローラー/スクレイピング Advent Calendar 2014の12日目の記事です。

ScrapyPythonにおけるクローリング・スクレイピングフレームワークとして有名ですが、Scrapydという興味深い機能があるので今日はこれを紹介します。

Scrapydはその名の通り、Scrapyのデーモンです。サーバーにおいてサービスとして動作し、Scrapyで作ったクローラーのジョブ管理ができます。

多くのページをクロールするクローラーにおいては、1回の実行時間が1日を超えることもしばしばあるので、ジョブ管理は重要です。このように運用を考慮した機能まで備えているのがScrapyの特徴的なところです。

Scrapydの概要

Scrapydは簡単なWebインターフェイスを提供しており、主にcurlを使ってAPIを呼び出します。

http://Scrapydをインストールしたホスト:6800 にアクセスすると、以下のようなシンプルな画面が表示されます。

f:id:mi_kattun:20141212224359p:plain

詳しくは後述しますが、Scrapyプロジェクトをデプロイしてある状態で以下のコマンドを実行すると、ジョブを実行できます。

curl http://Scrapydをインストールしたホスト:6800/schedule.json -d project=プロジェクト名 -d spider=スパイダー名

「Jobs」というリンクをクリックした先で実行中のジョブの状況を見られます。ジョブごとにログやスクレイプしたアイテムを見ることもできます。

f:id:mi_kattun:20141212224405p:plain

Scrapydのメリット

通常クローラーをデーモンとして動かすときは、Cronを使うと思います。ScrapydはCronと競合するツールではなく、Cronと組み合わせて使えるツールです。Scrapydを使うことで、Cron単体で使うときに比べて以下のメリットが得られます。

  • ジョブの実行状況を一覧で把握できる。
  • 同時に実行するジョブ数を制限できる。
  • Cronで定期的にジョブを実行するだけでなく、アドホックに実行できる。
  • HTTPのAPIで外部から簡単に操作できる。

Scrapydの使い方

以下のイメージでサーバーにデプロイします。

f:id:mi_kattun:20141212225022p:plain

Scrapydのインストール(サーバー側)

普通にpipでインストールしてsupervisordなどで管理することもできますが、Ubuntu向けにaptのパッケージが提供されています。せっかくなのでこれを使って楽をしてみましょう。

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 627220E7
$ echo 'deb http://archive.scrapy.org/ubuntu scrapy main' | sudo tee /etc/apt/sources.list.d/scrapy.list
$ sudo apt-get update
$ sudo apt-get install scrapyd

探せばDockerイメージやDockerfileを公開している人もいるので、それを使ってもよいでしょう。

※プロジェクトでScrapy以外のサードパーティライブラリ(例えばDBへのアダプタ)を使っている場合は、Scrapydと同じPython環境にインストールする必要があります。グローバル環境が汚れるのが気になる場合は、Virtualenv内にScrapydをインストールしてsupervisordなどで管理するのが良いでしょう。

初期設定(クライアント側)

Scrapyプロジェクトのフォルダにある scrapy.cfg[deploy] セクションにあるurlをScrapydのURLに書き換えます。

# Automatically created by: scrapy startproject
#
# For more information about the [deploy] section see:
# http://doc.scrapy.org/en/latest/topics/scrapyd.html

[settings]
default = helloscrapy.settings

[deploy]
# ここのurlを書き換える
url = http://192.168.33.10:6800/
project = helloscrapy

ブラウザで http://Scrapydをインストールしたホスト:6800 にアクセスして上で紹介したスクリーンショットのような画面が表示されることを確認しましょう。

デプロイ(クライアント側)

Scrapyプロジェクトのディレクトリで、以下のコマンドを実行するだけで現在のプロジェクトがegg化され、Scrapydにデプロイされます。

$ scrapy deploy
Packing version 1418386468
Deploying to project "helloscrapy" in http://192.168.33.10:6800/addversion.json
Server response (200):
{"status": "ok", "project": "helloscrapy", "version": "1418386468", "spiders": 2}

ジョブの実行(クライアント側)

以下のようにしてAPIを叩くことで、クローラーが動き始めます。

$ curl http://Scrapydをインストールしたホスト:6800/schedule.json -d project=プロジェクト名 -d spider=スパイダー名
{"status": "ok", "jobid": "722f9a7281f811e4b62808002743bc76"}

HTTPのAPIを叩くだけなので、Cronからも簡単に起動できます。Cronでありがちな環境変数の問題にハマることも少ないでしょう。また、外部のホストからも簡単にトリガーできるので、私はCronではなくJenkinsを使って定期的にクローラーを起動しています。

まとめ

いかがでしたでしょうか。若干使いにくいところもあるScrapydですが、クローラーの実行状況をまとめて管理できるので見通しが良くなります。Scrapydを使って快適なScrapy運用ライフを送りましょう!

Scrapydの機能はそんなに多くないですが、紹介しきれてはいないので詳しくはドキュメントをご覧ください。

http://scrapyd.readthedocs.org/en/latest/

今回使用したScrapyのバージョンは0.24ですが、Scrapydのドキュメントには古い記述が混ざっているようなのでお気をつけ下さい。