Tech memo of scrapy

Scrapyを使ったスクレイピングのメモ

Scrapyを使ったスクレイプのやり方と、その流れと、雑多なメモ

インストール~初期設定

pipでやるだけ。 startprojectをするとPROJECTNAMEのディレクトリができ、そのディレクトリ以下にいいかんじデータを揃えてくれる。

#インストール
$ pip install scrapy 

#プロジェクトの作成
scrapy startproject PROJECTNAME

scrapy shellを使ったパーサーの確認

startprojectで作成されたディレクトリにspidersというディレクトリができているので、そこにクローラーを書いていく流れになる。 ただ、毎回spiderを起動してパーサーを書くってなるとリソースの無駄になるので、ある程度パーサーの動作確認だけをおしておきたくなる。そのときに使うのがscrapy shell

$ scrapy shell 'https://www.yahoo.co.jp'

...log...

> response.css('a').getall()

上のように書くとヤフートップページのリンクがshellに表示される。

よく使うセレクタ

# attribでタグのattributeを取得
response.css('a').attrib['href']

# textをつけるとタグのテキストを取得できるgetをつけないとオブジェクトになる
response.css('a::text').get()

# あるcssセレクタ全部を取得して、forで回す
# Sampleというclassがついたdivのaタグを取得する
for i in response.css('div.Sample'):
    yield {
        'title': i.css('a::text').get(),
    }

他にもXpathも使えるし、reを使った正規表現も使える。 Selectors — Scrapy 2.4.1 documentation

全部覚えるというかは必要に応じてドキュメント見る。

spiderの作成

パーサー動作確認ができたら、spiderにしていく

import scrapy

class SampleSpider(scrapy.Spider):
    #ここに指定したnameをコマンドラインで指定する
    name="sample"

    def start_requests(self):
        urls = [
            'https://www.yahoo.co.jp/'
        ]
        for url in urls:
            #callbackに指定したメソッドがパーサーとして渡される
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        response.css('title::text').get()
            yield {
                'title': response.css('title::text').get()
            }

spiderの起動方法

scrapyのコマンドで作成したspiderを呼ぶ

# -O を指定してファイルにアウトプットする
scrapy crawl sample -O sample.json

コマンドライン引数をspiderに渡す

-a をつけると引数を指定できる 引数をspider側で取得する場合はgetattrを使う

#-a をつける複数ある場合は-aも複数つける
scrapy crawl sample -O sample.json -a id=test

#spiderの中身
class SampleSpider(scrapy.Spider):
    #ここに指定したnameをコマンドラインで指定する
    name="sample"

    def start_requests(self):
        #getattrでコマンドライン引数idを取得できる
        crawlid=getattr(self, 'id', None)
        urls = [
            'https://www.yahoo.co.jp/'
        ]
        for url in urls:
            #callbackに引数を指定したい場合、cb_kwargsをつかう
            yield scrapy.Request(url=url, callback=self.parse, cb_kwargs={'crawlid': crawlid})

    def parse(self, response):
        response.css('title::text').get()
            yield {
                'title': response.css('title::text').get()
            }

setting.pyの設定

プロジェクトのディレクトリにあるsettings.pyを使うと、spiderの動作の設定ができる。

#UserAgentを設定する。
USER_AGENT  = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'

#CONCURRNET_REQUESTSでリクエストの並列数を指定する。デフォルト16
CONCURRENT_REQUESTS = 1

#1回のクロールの間隔を設定する
DOWNLOAD_DELAY = 5

クロール間隔は5に設定しても、scrapy内部で1~1.5倍にしてランダムにしてくれる。 あと、CONCURRENTの設定がデフォルトで16(!?)なので何も知らないで100リクエストとかやってしまうとDosになってしまうので注意が必要。

とりあえずこんな感じ。ドキュメントが充実しているので、ドキュメントのチュートリアルを読んでそこを基本に深堀りしていくとやりやすかった。

Scrapy Tutorial — Scrapy 2.4.1 documentation

connvoi's Picture

About connvoi

肉とビールと料理と写真とゲーム たまに技術 python / Solr / PHP / ansible

アマゾンセール情報サイト アマセール管理人

Jp, Tokyo https://connvoi.com