DISTRICT 37

なにか

Scrapyチュートリアル

インストール

前回記事より。 dragstar.hatenablog.com

プロジェクトの作成

まずはプロジェクトを作る

scrapy startproject tutorial

ツリー構成はこんな感じ

tutorial/
├── tutorial
│   ├── __init__.py
│   ├── items.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       └── __init__.py
└── scrapy.cfg

一番上のディレクトリをホームとする

Itemの作成

スクレイピングした結果をItemクラスに保持することになる。items.pyにItemを定義する。

# items.py
import scrapy

class MyItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()

どういった情報を保持していくか、用途に合わせて項目を定義していく。

Spiderの作成

実際にスクレイピングをしてくれるSpiderを作る。処理の中でItemにデータを入れるのを忘れずに

# spiders.py
import scrapy
from scrapy.selector import Selector
from tutorial.items import MyItem

class MySpider(BaseSpider):
    name = "MySpider" #spiderに名前を付ける。実行時に使う
    allowed_domains = ["test.com"]
    start_urls = [
        "http://www.test.com/foo/bar"
    ]

    def parse(self, response):
        item = MyItem() 
        sel = Selector(response)

        ## この辺でスクレイピング処理を書いていく
        item['title'] = sel.xpath('//html/head/title/text()').extract()
        item['link'] = sel.xpath('//a/@href').extract()
        yeild item

コツとしてはFirefoxとかで対象サイトの要素をあらかじめ見ておくと希望するものにたどり着きやすい。よっぽどのサイトでなければCSSとかちゃんとやってるのでクラス指定とかID指定とかするとよりいい感じで取得できる。

shell

scrapy shellを動かして試しながらの使い方がおすすめ。xpathの使い方に慣れることができる。また、Itemにどんな感じで帰ってくるかも確認できるのでその後のpipeline作成にも役に立つ。

scrapy shell "http://www.test.com"

Pipelineの作成

スクレイピングした結果を料理するのがPipeline

# pipelines.py
class MyPipeline(object):
    def process_item(self, item, spider):
        # Spiderが実行されてitemに格納されるのでitemをDBにいれるなりなんなり
        t = item['title']
        link_list = item['link'] # listで帰ってくると仮定
        for l in link_list:
            print(l)

        return item

パイプラインを有効にするにはsettings.pyを変える。コメントアウトされているので外して、作ったpipelineを指定する

# settings.py
ITEM_PIPELINES = {
    'tutorial.pipelines.MyPipeline': 300,
}

jsonとかで出力できるので、必要なければpipelineはなくてもいい。

実行

例は実行して結果をjson形式に出力するコマンド

scrapy crawl MySpider -o output.json

CSVで出力するコマンド

scrapy crawl MySpider -o output.json

CSVに出力するやりかた。拡張子で勝手に判定してくれる

scrapy crawl MySpider -o output.csv

他にもログを残すやり方とか

scrapy crawl MySpider --logfile scrapy.log

スケジューリング

と、うまくいったら勝手に実行してほしいですよね。スケジューラはcrontabでもなんでもいいけど、実行するときのシェルスクリプトにちょっと手間取った。

export PATH=$PATH:/home/xxxx/.pyenv/shims

cd tutorial

scrapy crawl MySpider --logfile scrapy.log

こんな感じにした。うまくscrapyへのパスを指定しないと「scrapyなんてコマンド知りませんけど」ってなる。僕の場合はpyenvを使っているのでscrapyのパスも/home/xxxx/.pyenv/shimsにあったのでそれを指定した。which scrapyとかで探せばいい。あとはプロジェクトのホームディレクトリに移動して実行コマンドを打つ、といったスクリプト。実行権限も必要に応じて。

最後に

クローラは自動ゆえ便利だが、頻繁に実行すると当然相手サーバにアクセスすることになる。先方に迷惑がかからない程度に節度をもってやりましょう。こんな事件も昔にあった事ですし、、、

岡崎市立中央図書館事件 - Wikipedia