Scrapyでイベントサイトの更新情報を定期ツイート on Heroku
目的
以前書いたスクリプトのリプレイス。
以下問題点を解消したかった。
- 可読性 : フレームワークを使わずにbeautifulsoupで書いてた(beautifulsoupは悪くない)
- パフォーマンス : 同期通信だからおっそい
- 制約下の縛りプレイ : Herokuにクレカ登録してなかった(詳細は後述)
クレカは登録したけれど無料で運用する意思は貫いてます。
パッケージ管理
pipenvを使用。
HerokuはPipfileに対応してるため、requirements.txtをわざわざ作成する必要もないです。
参考
インストールしたパッケージ
scrapy
djangoライクなテンプレートを提供してくれるため、
データの定義・取得・バリデーション・保存・アウトプットに関するコードの棲み分けがしやすい。
あと非同期通信。特に意識せず実装できるすごい。
download-delayの設定はお忘れなく
scrapy-selenium
scrapyでselenium使うためのmiddleware
スクレイピングしてて、あれ?取れない??DevToolsでは見れるのにってなった際、
インストールすれば幸せになれるはず。
READMEより
SELENIUM_DRIVER_NAME = 'firefox'
SELENIUM_DRIVER_EXECUTABLE_PATH = which('geckodriver')
chromedriver使うならこう!
SELENIUM_DRIVER_NAME = "chrome"
SELENIUM_DRIVER_EXECUTABLE_PATH = which("chromedriver")
redis
前回取得した記事のidを保管
rdbsを使うまでもないし、IOのパフォーマンスもいいし、Herokuのプラグインもあったので。
クレカ登録しないとプラグインインストールできません
ローカルで動かすときはdockerコンテナ立てました。
こちら参考にさせて頂きました。
これは前回と同じの。api使うための認証情報とツイート本文を与えるだけでお手軽ツイート
プロジェク作成
$ mkdir project
$ cd project
$ pipenv install scrapy
# プロジェクトのディレクトリをカレントディレクトリに作成
$ pipenv run scrapy startproject project .
$ mkdir project
$ cd project
$ pipenv install scrapy
# プロジェクトのディレクトリをカレントディレクトリに作成
$ pipenv run scrapy startproject project .
その後の具体的な実装はGitHubで。
スクレイピングするurlは環境変数で与えるようにしてます。
構成はこんな感じ。
event_notify #プロジェクトルート
├── event_notify
│ ├── items.py # 取得項目の定義
│ ├── pipelines.py # 取得項目のバリデーション〜アウトプット
│ ├── settings.py # 各種設定
│ └── spiders
│ └── eventsite.py # スクレイピング
├── example.env #環境変数(サンプル)
簡単な流れ
- イベント情報サイトの検索結果を取得
- 次のページがある場合はそちらも再帰的に取得
- 各イベントのページもスクレイピングして、タイトル・url・開催場所・値段・販売状況等取得
- 取得した情報に空のフィールドがあったら捨てる
- redisから前回取得したイベントのリストを取得して変数に保持(実行時1度のみ)
- redisを空に(実行時1度のみ)
- redisに今回取得イベントを追加
- if 今回取得イベント in 変数 : 捨てる
- 捨てられなかったイベントはツイート
Herokuにデプロイ
bitbucketではこんな感じでやってましたが、Githubではめっちゃ簡単に出来ました。
マニュアルを見るまでもなく、HerokuのGUIからポチポチーで秒で出来ます。
GitHubのmasterにpushされたらherokuのmasterにpushってよくあるパターン。
Heroku アドオン
定期実行
Heroku Scheduler
無料プランだと、実行間隔を10分・1時間・1日の3択からしか選べない
redis
heroku-redisを使用。無料枠あり。
GUIからデータは見れないので、CLIからredisのコマンド叩いて確認。
ログ管理
Papertrail
概要はこちらが参考になるかと。
scrapyのログレベルをデフォルト(DEBUG)のままにしてると、
フリープランの場合すぐに限界量(10MB/1day)に達してしまうため、INFOに変更推奨。
あと、redisのヘルスチェックもPapertrail側のフィルターで無視しておくと良きかと。
LOG_LEVEL = "INFO"
chromedriver
chromedriverをHeroku上でも使うため下記インストール
- https://github.com/heroku/heroku-buildpack-google-chrome.git
- https://github.com/heroku/heroku-buildpack-chromedriver.git
VSCodeでのデバッグ
構成の追加ボタンからScrapy用のテンプレートを追加すれば簡単にデバッグ可能。
これ地味にすごいありがたい
無料枠について
クレカ登録すると無料枠が拡張されるのと、各プラグインがインストールできるようになります。
プラグインには無料プランがある(ものもある)ので普通に無料で運用できます。
前回紹介したプラグインを使わないタスクスケジューリング方法では、
結局タスクを実行させるcron的なプロセスは動いてるので無料枠が消費されました。
クレカ登録してないので課金は絶対されないけれど。
今回紹介したスケジューラプラグインの場合、
実行中しか枠を消費しないので、拡張された無料枠が食い尽くされることはないです。
というかdyno1つが24時間稼働しても課金枠には及ばなかったような(詳細は調べてください)
感想
今までbeautifulsoupでゴリゴリ書いてたけど
scrapyで書き直したらほんと見通しがよくなりました。
jupyterでさらっと書きたいとき以外はscrapy使ってこうと思いますた。ほんとおすすめ。
Author And Source
この問題について(Scrapyでイベントサイトの更新情報を定期ツイート on Heroku), 我々は、より多くの情報をここで見つけました https://qiita.com/nkg/items/cb27a117390ff7ef03c8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .