Webページのスクレイピングと分析・可視化で使用したPython製WebクローラScrapyについて覚えたことについて記載する。
本記事はメモ程度の内容であり、情報の正確性については保証しない。必ず公式ドキュメントを参照すること。
サンプルコード
サンプルコード1
import scrapy
class QiitaCalendarSpider(scrapy.Spider):
name = "qiita_calendar"
allowed_domains = ["qiita.com"]
start_urls = ["http://qiita.com/advent-calendar/2016/calendars"]
custom_settings = {
"DOWNLOAD_DELAY": 1,
}
def parse(self, response):
for href in response.css('table.table.adventCalendarList tbody tr'):
calendar_title = href.css('td.adventCalendarList_calendarTitle a::text').extract_first()
calendar_url = href.css('td.adventCalendarList_calendarTitle a::attr(href)').extract_first()
calendar_attendees = href.css(
'td.adventCalendarList_progress span.adventCalendarList_recruitmentCount::text').extract_first()
yield {
'calendar_title': calendar_title,
'calendar_url': response.urljoin(calendar_url),
'calendar_attendees': calendar_attendees
}
for page in response.css('li.hidden-xs a'):
next_page = page.css('::attr(href)').extract_first()
if next_page is not None:
next_page = response.urljoin(next_page)
yield scrapy.Request(next_page, callback=self.parse)
サンプルコード2
def start_requests(self):
qiita_calendars = QiitaCalendarLoader()
for url in qiita_calendars.urls():
yield scrapy.Request(url=url, callback=self.parse)
コーディング
DOWNLOAD_DELAYは最初に設定するべき
DOWNLOAD_DELAY
はクロール毎のインターバル時間を秒単位で設定するプロパティ。これを設定しないと簡単にWebサイトにDoSアタックをかけることになる。絶対に一番最初に設定すること。
allowed_domains
必須ではないものの設定推奨。このリストに含まれるドメインしかクロールしない。
レスポンスの取扱い
parse(self, response)
で渡されるresponse
で主に使うのはtext
、css()
、urljoin()
の3つ。
response.text
はhtml情報がテキスト形式で入っているので、このままBeautifulSoupに渡すことができる。
response.css()
はCSSセレクタによりhtml内の任意のセクションのSelectorインスタンスのリストを返す。インスタンスに含まれるデータは extract()
でアクセス可能。リストのままでも、extract_first()
で最初の要素に対してのみextract()
をかけることが可能。
response.urljoin(path)
は、path
と現在クロールしているURLを合わせてURLのフルパスを返す。
start_urls と start_requests()
最初にクロールするURLの一覧はリストstart_urls
に書く以外に、start_requests()
でyieldするという方法がある。(サンプルコード2)
今回の例では、カレンダー一覧ページで取得したカレンダーURLを含むjsonをロードし(QiitaCalendarLoader
)、そのURLに対してクロールするという処理を行っている。
コマンド
プロジェクト作成
scrapy startproject <プロジェクト名>
で作成可能。
参考: https://doc.scrapy.org/en/1.3/topics/commands.html#genspider
Spider生成
scrapy genspider <スパイダー名> <対象ドメイン>
で作成可能だが、大したことはしないので別に使わなくてもいい。
参考: https://doc.scrapy.org/en/1.3/topics/commands.html#genspider
クローリング
scrapy crawl <スパイダー名>
プロジェクトを作成した場合はcrawlコマンドを使う。
参考: https://doc.scrapy.org/en/1.3/topics/commands.html#crawl
インタラクティブシェル
scrapy shell <URL>
ipythonによるインタラクティブシェルモードに入る。URLは省略可。
URLを指定した場合、既に response 変数にレスポンスが格納されている。
インタラクティブシェルモードを起動するとヘルプが表示されるが、特に覚えるべきメソッドは2つ。
shelp()
ヘルプを表示する。
fetch(url)
あらたにURLをクロールする。結果はresponseに格納される。
settings.py
プロジェクトを作成すると、settings.py
という設定ファイルが作成される。DOWNLOAD_DELAY
など、全てのスパイダーで共通の設定を行うものはこちらに記述した方がいい。