Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pythonで作るWebクローラ入門

amacbee
September 21, 2016

 Pythonで作るWebクローラ入門

Pythonで作るWebクローラ入門の発表資料
https://pycon.jp/2016/ja/schedule/presentation/32/

amacbee

September 21, 2016
Tweet

More Decks by amacbee

Other Decks in Technology

Transcript

  1. Python
    で作るWeb
    クロー
    ラ入門
    真嘉比 愛(Ai Makabi)
    2016-09-21 @PyConJP 2016
    Room 203 #pyconjp_203

    View Slide

  2. 真嘉比愛(Ai Makabi)
    DATUM STUDIO
    株式会社
    PyLadies Tokyo
    各種アカウント
    Slack: @amacbee
    Twitter: @a_macbee
    Facebook: ai.makabi
    Python
    ライブラリ厳選レシピ(
    共著)

    View Slide

  3. Web
    クロー
    ラとは?

    利用事例や注意点を添えて ~

    View Slide

  4. Web
    クロー

    Wikipedia
    より抜粋
    混同されがちな言葉
    クロー
    リング:
    Web
    ペー
    ジのリンクを辿りながら保存する作業
    スクレイピング:
    保存したペー
    ジから特定の情報を抽出する作業
    クロー
    ラ(Crawler)
    とは、
    ウェブ上の文書や画
    像などを周期的に取得し、
    自動的にデー
    タベー

    化するプログラムである。


    View Slide

  5. クロー
    ラの利用事例
    クロー
    ラで情報を収集して分析…
    という流れは多い
    類似映画検索システム
    EC
    サイトのトレンド分析システム
    株価トレンド分析システム
    Twitter
    センチメント抽出システム
    etc.

    View Slide

  6. クロー
    ラの利用事例
    クロー
    ラで情報を収集して分析…
    という流れは多い
    類似映画検索システム
    EC
    サイトのトレンド分析システム
    株価トレンド分析システム
    Twitter
    センチメント抽出システム
    etc.

    View Slide

  7. 事例1:
    類似映画検索
    数十万件/3
    ヶ月.Azure
    上で動作

    View Slide

  8. 事例2: EC
    サイトのトレンド分析
    約100
    万件/
    日(10
    数台で7~8
    時間).GCP
    上で動作

    View Slide

  9. クロー
    ラを利用してデー
    タを
    収集することで
    デー
    タ分析の幅が圧倒的に広がる

    View Slide

  10. 本セッションの内容
    Python
    を利用したクロー
    ラ作成・
    運用方法を一通り
    知ることを目標とする
    1. Web
    クロー
    ラを利用する上での注意点
    2. Python
    製クロー
    ラフレー
    ムワー
    ク「Scrapy」
    Scrapy
    を利用してPyJobBoard
    クロー
    ラを作成
    クロー
    ラ作成のTips
    作成したクロー
    ラの管理
    3.
    その他クロー
    ラ構築に有用なPython
    ライブラリ

    View Slide

  11. 時間の都合上省略
    BeautifulSoup4
    を中心とした各種スクレイピング
    ライブラリについて
    JavaScript
    を解釈するクロー
    ラの話(scrapy-
    splash, Selenium)
    上記の内容を聞きにきて頂いた方がいましたら申し訳
    ありませんm(_ _;)m
    またの機会に話したいです

    View Slide

  12. クロー
    ラを作成する上での注意点

    View Slide

  13. 岡崎市立中央図書館事件
    事件概要:
    図書館の蔵書検索システムを日常的にクロー
    ルしてい
    た男性が,
    高頻度のリクエストを故意に送りつけシス
    テムに接続障害を与えたとして偽計業務妨害容疑で逮
    捕された(
    別名:LibraHack
    事件)
    -->
    収集したデー
    タの使用目的やスクレイピング方法
    によっては,
    法に触れることもある

    事件自体は違法性はなかったと考えられている

    View Slide

  14. クロー
    リングの際に遵守したいこと
    デー
    タの収集/
    公開は著作権法に配慮して行う
    robots.txt
    に記載されたアクセス制限を守る
    API
    が容易されている場合はそちらを利用する
    サー
    バへアクセスする間隔は最低でも1
    秒以上あけ
    るようにする
    会員のみが閲覧できるペー
    ジは利用規約を守る
    参考:Web
    スクレイピングの注意事項一覧

    View Slide

  15. Python
    でお手軽に
    クロー
    ラを書きたい!

    View Slide

  16. クロー
    ラフレー
    ムワー

    View Slide

  17. Scrapy - latest: 1.1.2
    Python
    製のクロー
    ラフレー
    ムワー

    クロー
    ラ界におけるDjango
    のような存在
    クロー
    ラ作成時に考慮しなければならない機能を
    オプションを指定するだけで簡単に実現可能
    e.g.
    サイトクロー
    リング間隔,robots.txt
    の解釈
    スケジュー
    リング,
    ジョブ管理,etc.
    機能を内包
    2016
    年5
    月にリリー
    スされたScrapy 1.1
    より
    Python 3
    に対応

    View Slide

  18. Scrapy Architecture
    各機能はコンポー
    ネントに分かれている

    View Slide

  19. Scrapy
    利用環境の構築
    pip
    を使って簡単に導入できます
    $ pip install scrapy
    ※Windows
    環境の場合,
    別途設定が必要
    ※Ubuntu
    環境ではapt-get
    も利用可能
    $ sudo apt-get install python-scrapy

    View Slide

  20. Scrapy
    を利用して
    PyJobBoard
    クロー
    ラを作成
    (Hello Scrapy!)

    View Slide

  21. www.python.org/jobs
    複数の企業のジョブオファー
    が列挙されている
    募集内容・
    勤務地・
    企業名の情報が記載されている
    下部に次のペー
    ジへ行くためのリンクがある

    View Slide

  22. Scrapy
    を用いたクロー
    リングの流れ
    www.python.org
    のサイトにあるJob Board
    をクロー
    ルするクロー
    ラを作成する
    以下の手順を踏みます
    1.
    プロジェクトを作成
    2.
    クロー
    ル対象を定義
    3.
    クロー
    ラを作成
    4.
    クロー
    リング&
    結果の保存

    View Slide

  23. 1.
    プロジェクトを作成
    $ cd
    任意のフォルダ
    $ scrapy startproject
    プロジェクト名
    e.g. pyjob
    プロジェクト


    ─ pyjob
    │ ├

    ─ __init__.py
    │ ├

    ─ __pycache__
    │ ├

    ─ items.py #
    クロー
    ル対象について記載
    │ ├

    ─ pipelines.py
    │ ├

    ─ settings.py #
    クロー
    ルオプション
    │ └

    ─ spiders #
    クロー
    ラ本体(spider)
    を格納
    │ ├

    ─ __init__.py
    │ └

    ─ __pycache__


    ─ scrapy.cfg #
    デプロイ設定

    View Slide

  24. 2.
    クロー
    ル対象を定義
    scrapy.Field()
    を利用して,
    取得したい情報を
    item.py
    に追記(
    今回は募集タイトル・
    社名・
    勤務場
    所)
    import scrapy
    class PyjobItem(scrapy.Item):
    title = scrapy.Field() #
    タイトル
    company = scrapy.Field() #
    社名
    location = scrapy.Field() #
    勤務場所

    View Slide

  25. 3.
    クロー
    ラを作成(1/7)
    scrapy genspider
    コマンドで雛形となるクロー

    (spider)
    を自動的に作成
    $ scrapy genspider
    クロー
    ラ名 クロー
    ル対象ドメイン
    例えば, python.org
    ドメインをクロー
    ルするクロー

    の雛形を作成するには以下の通り実行
    $ cd pyjob
    $ scrapy genspider pyjob_spider python.org

    作成されたクロー
    ラはpyjob/spiders
    以下にある

    View Slide

  26. 3.
    クロー
    ラを作成(2/7)
    作成したクロー
    ラの雛形の中身
    自動作成された変数
    name:
    クロー
    ラ名
    allowed_domain:
    クロー
    ル対象ドメイン
    start_urls:
    クロー
    ル開始ペー
    ジのURL
    リスト
    自動作成されたメソッド
    parse:
    クロー
    ルしたペー
    ジのパー
    ス ※
    後述

    View Slide

  27. 3.
    クロー
    ラを作成(3/7)
    e.g. python.org
    ドメイン中の python.org/jobs
    ペー

    を起点にクロー
    リング
    from ..items import PyjobItem
    import scrapy
    class PyjobSpiderSpider(scrapy.Spider):
    name = "pyjob_spider"
    allowed_domains = ["python.org"]
    start_urls = (
    'https://www.python.org/jobs/',
    )
    def parse(self, response): #
    後述

    複数のドメイン・URL
    を指定可能

    View Slide

  28. 3.
    クロー
    ラを作成(4/7)
    parse
    メソッドでは主に2
    つの処理を行う
    1.
    ペー
    ジからクロー
    ル対象の要素を抽出して返す
    Item
    クラスに必要な情報を格納
    ※Item
    クラスの定義はitem.py
    で定義
    2.
    次のクロー
    ル対象ペー
    ジのURL
    を返す
    scrapy.Request(url)
    で返されたURL
    は新たなクロ

    リング対象となる(callback
    引数にparse
    メソ
    ッドを指定すると,
    再帰的にクロー
    ルを実行)

    View Slide

  29. 3.
    クロー
    ラを作成(5/7)
    def parse(self, response):
    #
    ペー
    ジ中のジョブオファー
    情報を全て取得
    for res in response.xpath("//h2[@class='list..."):
    job = PyjobItem()
    job['title'] = res.xpath(".//span[@cla...")...
    job['company'] = res.xpath(".//span[@cla...")...
    job['location'] = res.xpath(".//a[start...")...
    yield job
    # 「Next」
    のリンクを取得してクロー
    ルする
    next_page = response.xpath("//li[@cla...").extract()
    if next_page:
    url = response.urljoin(next_page[0])
    yield scrapy.Request(url, callback=self.parse)
    タグ要素の取得にはXPath
    やCSS
    のセレクタを利用

    View Slide

  30. 3.
    クロー
    ラを作成(6/7)
    settings.py
    でクロー
    リングのオプションを設定
    絶対に設定して欲しい項目は以下
    パラメー
    タ 意味
    DOWNLOAD_DELAY
    クロー
    ル間隔(
    秒)
    robots.txt
    に従うか否かを設定する ROBOTSTXT_OBEY

    デフォルトで True (Scrapy 1.1+)

    View Slide

  31. 3.
    クロー
    ラを作成(7/7)
    e.g. pyjob
    のクロー
    リングオプション設定
    BOT_NAME = 'pyjob'
    SPIDER_MODULES = ['pyjob.spiders']
    NEWSPIDER_MODULE = 'pyjob.spiders'
    ROBOTSTXT_OBEY = True # robots.txt
    に従う
    DOWNLOAD_DELAY = 3 #
    同一サイトへのアクセス間隔は3

    View Slide

  32. 4.
    クロー
    リング&
    結果の保存
    $ scrapy crawl
    作成したクロー
    ラ名 -o
    出力先ファイル名
    e.g. pyjob
    クロー
    ラを実行して,
    結果をCSV
    形式で保
    存(
    クロー
    リングの実行ログも残す)
    $ scrapy crawl pyjob_spider -o result.json \
    --logfile pyjob.log

    拡張子からファイルタイプを自動判定
    ※DB
    等へデー
    タを保存する処理は, pipeline.py
    を編
    集することで追加できるが,
    ここでは省略

    View Slide

  33. クロー
    リング結果を確認
    result.json
    [
    {
    "title": "Lead Python API and Automation Developers",
    "location": "Remote, USA",
    "company": "FICO"
    },
    {
    "title": "Python Developer",
    "location": "London, UK",
    "company": "BMLL Technologies"
    },
    ...

    View Slide

  34. クロー
    リングログを確認
    pyjob_spider.log
    2016-09-21 01:20:30 [scrapy] INFO: Scrapy 1.1.2 started
    (bot: pyjob)
    2016-09-21 01:20:30 [scrapy] INFO: Overridden settings:
    {'NEWSPIDER_MODULE': 'pyjob.spiders',
    'LOG_FILE': 'pyjob_spider.log',
    'BOT_NAME': 'pyjob',
    'SPIDER_MODULES': ['pyjob.spiders'],
    'FEED_URI': 'result.json',
    'ROBOTSTXT_OBEY': True,
    'DOWNLOAD_DELAY': 3,
    'FEED_FORMAT': 'json'}
    2016-09-21 01:20:30 [scrapy] INFO: Enabled extensions:
    ['scrapy.extensions.corestats.CoreStats',
    ...

    View Slide

  35. クロー
    ラ作成のTips(1/3)
    Google Chrome
    の「
    デベロッパー
    ツー
    ル」
    を使う
    と3
    ステップでスクレイピング箇所を特定出来る

    View Slide

  36. クロー
    ラ作成のTips(2/3)
    scrapy shell
    を利用してスクレイピング結果をイン
    タラクティブに確認
    $ scrapy shell 'https://www.python.org/jobs/'
    ...
    >>> response.css('title')
    [data='Python Job Board | Python.org]
    >>> response.xpath('//title')
    [data='Python Job Board | Python.org]
    ※ requests + BeautifulSoup4
    でも代替出来る

    View Slide

  37. クロー
    ラ作成のTips(3/3)
    クロー
    リング過程とスクレイピング過程を分ける
    サイト構造の変更によるスクレイピングの失敗
    は珍しくない
    =>
    失敗してもクロー
    リングを再実行しない
    =>
    クロー
    リング/
    スクレイピング共に失敗して
    いないか監視する
    対象サイトにJavaScript
    が含まれているか確認する
    JavaScript
    が含まれるか含まれないかで難易度が
    大きく変わるため,JavaScript
    が含まれる場合は
    別サイトの利用も検討する

    View Slide

  38. [
    まとめ]
    クロー
    ラ作成 with Scrapy
    以下の手順を踏むことで,
    特定サイトから欲しいデー
    タをクロー
    ル出来た
    1.
    プロジェクトを作成
    2.
    クロー
    ル対象を定義
    3.
    クロー
    ラを作成
    4.
    クロー
    リング&
    結果の保存

    View Slide

  39. 作成したクロー
    ラを
    管理するにはどうするのか?

    View Slide

  40. クロー
    ラ管理
    Scrapy
    専用の管理ツー
    ルを2
    つ紹介
    Scrapy Cloud
    scrapyd

    View Slide

  41. Scrapy Cloud
    クロー
    ラ管理用クラウドサー
    ビス「scrapinghub」
    上で動くScrapy
    環境
    https://scrapinghub.com/scrapy-cloud/
    Scrapy Clound
    の便利なポイント
    ツー
    ルの導入が簡単( pip install shub )
    API
    キー
    を使って簡単deploy( shhub login -->
    shub deploy )
    簡易かつリッチなUI
    スケジュー
    リングも容易( Periodic Jobs )

    View Slide

  42. Scrapy Cloud
    の課金体系
    クロー
    ル範囲が1
    サイト以下の場合は 無料
    クレジットカー
    ドの登録も必要なし
    デー
    タ保存期間は1
    週間
    新しくクロー
    ル先を追加するたびに +9$ / month
    https://scrapinghub.com/pricing/

    View Slide

  43. scrapyd
    Scrapy
    のデー
    モン
    作成したクロー
    ラのジョブ管理が行える
    インストー
    ルが容易
    ( pip install scrapyd scrapyd-client )
    シンプルなAPI
    を利用した操作
    ※ Python 3
    に対応していない

    View Slide

  44. クロー
    ラをscrapyd
    にdeploy
    1. scrapy.cfg
    の [deploy]
    にあるurl
    をコメントアウト
    [deploy]
    url = http://localhost:6800/
    project = pyjob
    2. scrapyd
    を起動
    $ scrapyd
    3.
    作成したクロー
    ラをscrapyd
    にdeploy
    $ scrapyd-deploy -p pyjob

    View Slide

  45. API
    を利用したジョブの登録
    schedule.json:
    ジョブを登録
    $ curl http://localhost:6800/schedule.json \
    ß-d project=pyjob -d spider=pyjob_spider
    cancel.json:
    ジョブの中止
    $ curl http://localhost:6800/cancel.json \
    -d project=pyjob -d job=
    ジョブID
    その他のAPI:
    https://scrapyd.readthedocs.io/en/stable/api.html

    View Slide

  46. クロー
    ラ作成に最適な
    Python
    ライブラリの紹介

    View Slide

  47. クロー
    ラ向けライブラリ(1/2)
    1. requests
    人間が利用することを意識して書かれた非常にシ
    ンプルなHTTP
    ライブラリ

    その限りではないが)
    使い捨てのコー
    ドを書く
    のに最適
    >>> import requests
    >>> res = requests.get('http://www.python.org/jobs/')
    >>> res.status_code
    200
    >>> with open('pyjob.html') as fout:
    ... fout.write(res.content)

    View Slide

  48. クロー
    ラ向けライブラリ(2/2)
    2. aiohttp
    Python 3.4
    から追加されたasyncio
    を利用した非同期
    HTTP Server/Client
    1
    プロセス内で複数のリクエス
    トを同時に実行(=IO
    多重化)
    =>
    待ち時間を有効に活用して
    高速に動作
    公式サイト:
    http://aiohttp.readthedocs.io

    View Slide

  49. e.g. aiohttp
    を利用したシンプルなクロー

    from aiohttp import request, wait
    import asyncio
    @asyncio.coroutine
    def get(*args, **kwargs):
    res = yield from request('GET', *args, **kwargs)
    return (yield from res.read_and_close())
    @asyncio.coroutine
    def print():
    page = yeild from get(url)
    print(page)
    urls = ['****', '****', '****']
    f = wait([print(url) for url in urls])
    loop = asyncio.get_event_loop()
    loop.run_untile_complete(f)

    View Slide

  50. 本日のまとめ

    View Slide

  51. 話したこと
    Web
    クロー
    ラについて説明
    クロー
    ラの利用事例を紹介
    クロー
    リング時の注意点について説明
    Scrapy
    を利用したクロー
    ラ構築方法を一通り説明
    クロー
    ラ構築方法について最低限の流れを説明
    クロー
    ラ構築時のTips
    について共有
    クロー
    ラの管理に便利なツー
    ルを紹介
    ありがとうございました!

    View Slide