AT's Blog

趣味のプログラミング、ギター、音楽とかとか

YouTubeで"Pythonで作るWebクローラ入門"を視聴した際のメモ

概要

Python"をキーワードにYouTubeで検索をかけると、PyConJPのセッション動画が複数ヒットします。

本記事は、それらの中から"Pythonで作るWebクローラ入門"を視聴した際のメモです。

セッション資料

PyConJP 2016のセッションで、Scrapyを使ったクローラ作成の入門がテーマです。

発表者はAi Makabi様。

www.youtube.com

speakerdeck.com

githubにコードが上がっているらしいのですが、発見できませんでした。

自力でコードの空白部分を埋めています。

クローラの仕様

python.orgのJob Boardから、ジョブオファーごとの募集内容・勤務地・募集企業をスクレイピングする。

www.python.org

ただし、Python Job BoardのHTML構成が変わったらしく、 私のスキルでは募集企業をうまく抽出できませんでした(正規表現を利用すれば抜き出せるかも)。

Scrapyインストール

セッションはScrapyがインストールされている前提で開始します。

下記のように、Scrapyはpipでインストールできます。 私は適当なディレクトリを切って、pyenv-virtualenv環境で利用しています。

pip install Scrapy

robots.txt

www.seohacks.net

クローラに対するアクセス制限を記述したファイルです。

テキスト形式で、通常はルートURLに置かれるようです。

セッション中では、クローラ利用時の注意事項に触れられており、robots.txtの順守を推奨しています。 逆にいえば、robots.txtを無視することもできますが、Scrapyはデフォルト設定ではrobots.txtを解釈してクローリングしてくれます。

XPath

qiita.com

XMLテキスト中の要素や属性を指定するための言語で、クローラ作成では必須だそうです。

ScrapyではXPathCSSの両セレクタが使用できます。

また、Beautiful Soupのセレクタを使用することもできるそうです。

今回は発表内容に合わせて、XPathを使用しました。

DOWNLOAD_DELAY

設定必須!!

setting.pyでリクエスト送信のディレイを指定します。 デフォルトでは0[sec]に設定されるので、下記のように設定してやります。 今回は3[sec]に設定しました。

DOWNLOAD_DELAY = 3

Spider

Python Job BoardのHTMLコードをChrome Developer Toolで解析しつつ、コードを実装しました。

# -*- coding: utf-8 -*-
from ..items import PyjobItem
import scrapy


class PyjobSpiderSpider(scrapy.Spider):
    name = 'pyjob_spider'
    allowed_domains = ['python.org']
    start_urls = ['http://python.org/jobs/']

    def parse(self, response):
        for res in response.xpath('//h2[@class="listing-company"]'):
            job = PyjobItem()
            job['title'] = res.xpath('.//span[@class="listing-company-name"]/a/text()').extract()
            job['location'] = res.xpath('.//span[@class="listing-location"]/a/text()').extract()
            yield job

        next_page = response.xpath('//li[@class="next"]/a/@href').extract()
        if next_page:
            url = response.urljoin(next_page[0])
            yield scrapy.Request(url, callback=self.parse)

pyjob_spider.py

実行結果

下記コマンドでクローリング実行し、json形式で結果を保存します。拡張子でファイルタイプを自動判定してくれます。

scrapy crawl pyjob_spider -o test.json 

実行結果を抜粋します。オファーのタイトルと、勤務地が保存されています。

[
{"title": ["Software Engineer - Python"], "location": ["San Francisco, CA, United States"]},
{"title": ["Back-End Developer"], "location": ["London, London, United Kingdom"]},
{"title": ["Director of Engineering"], "location": ["Mountain View, CA, United States"]},
{"title": ["Python / full-stack Developer"], "location": ["London, United Kingdom"]},
{"title": ["Software Product Engineer"], "location": ["Carmel, Indiana, United States"]},
{"title": ["Python Developer"], "location": ["New York, NY, USA"]},
{"title": ["SENIOR FULL-STACK WEB DEVELOPER - LIVE BLOG "], "location": ["BELGRADE, PRAGUE,BERLIN, Serbia, Czech republic, Germany"]},
{"title": ["Python Developer"], "location": ["Redruth, Cornwall, United Kingdom"]},
{"title": ["Senior Python Developer"], "location": ["Dublin, Ireland"]},
...
"title": ["Python/Django Developer"], "location": ["London, Greater London, United Kingdom"]},
{"title": ["Entry-level Python/Django Developer"], "location": ["LONDON, Greater London, United Kingdom"]},
{"title": ["Senior Bioinformatician/Analyst"], "location": ["Cambridge, United Kingdom"]},
{"title": ["Senior Bioinformatician"], "location": ["Cambridge, United Kingdom"]},
{"title": ["Junior Backend Developer"], "location": ["Sheung Wan, HK Island, Hong Kong"]},
{"title": ["Python Developer"], "location": ["Des Moines, Iowa, United States"]},
{"title": ["Cloud Systems Programmer (Remote)"], "location": ["Atlanta, GA, USA"]},
{"title": ["Experienced Python Developer"], "location": ["Houthalen, Belgium"]},
{"title": ["Senior Python Backend Developer (Ethereum Blockchain/RaidEX)"], "location": ["Mainz, Berlin, Copenhagen, Germany, Denmark"]}
]

test.json

Shellモード

XPathの設定については、セッション中でもTipsとして触れられていますが、 下記サイトも参考にしつつshellモードでセレクタを調査しました。

qiita.com

クローリング過程とスクレイピング過程の分離

Tipsとして、クローリング過程とスクレイピング過程の分離について触れられています。

分離のメリットは、

  1. サイト構造変更でスクレイピングに失敗しても、クローリングをやり直さずに済む
  2. クローリングとスクレイピングのどちらに問題があるか切り分けが容易

であると私は解釈しました。

まとめ・感想

XPathの設定にかなり手こずってしまいました。 逆に言えば、実装作業のほとんどはXPath記述に費やしており、慣れれば簡単にspiderを実装できそうです。