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になってしまうので注意が必要。
とりあえずこんな感じ。ドキュメントが充実しているので、ドキュメントのチュートリアルを読んでそこを基本に深堀りしていくとやりやすかった。