#はじめに
「Pythonクローリング&スクレイピング[増補改訂版]データ収集・解析のための実践開発ガイド」の学習まとめ
今回の第4章は「実用のためのメソッド」という章題でクローラーを作る際の注意点などを中心とした内容だった
#4.1 クローラーの特性
##4.1.1 状態を持つクローラー
-
ログインが必要なサイトをクロールする場合はCookieに対応するクローラーを作る
-
PythonのRequestsライブラリはSessionオブジェクトを使うことでCookieをサーバーに自動で送信してくれる
-
Referer
- 一つ前に閲覧したページのURLをサーバに送るためのHTTPヘッダー
- (例)Googleの検索結果からQiitaにアクセスしたときにChromeの検証ツールで確認するとこんな感じになってる
4.1.2 JavaScriptを解釈するクローラー
SPA(Single Page Application)として作られたサイトなどをクロールするにはJavaScript
を解釈する必要がある。そのためにはSeleniumやPuppeteerなどのブラウザを自動操作するためのツールを使う
また、ChromeやFireFoxなどのブラウザにはGUIなしで実行できるヘッドレスモードがあり、クローラの作成に役立てることができる
4.1.3 不特定多数のWebサイトを対象とするクローラー
Googlebotとかのこと。特定のサイトを対象とするクローラーよりも難易度が高い。
ページ構造に依存しない仕組みが必要。
#4.2 収集したデータの利用に関する注意
##4.2.1 著作権
クローラーを作成するときに注意するべき著作権→複製権・翻案権・公衆送信権
2009年の著作権法改正によって、情報解析を目的とした複製や検索エンジンサービスの提供を目的とした複製・翻案・自動公衆送信が、著作権者の許諾なく行えるようになってい
る
##4.2.2 利用規約と個人情報
サイトの規約を守ろうねというお話。
個人情報については個人情報保護法にもとづいて管理する。
#4.3 クロール先の負荷に関する注意
クロール先に負荷をかけない方法について。
岡崎市立中央図書館事件 - Wikipedia
こんな事件があったとは
##4.3.1 同時接続数とクロール間隔
- 同時接続数
- 最近のブラウザあ1ホストあたり最大6の同時接続を張るが、クローラーは長時間複数のページを取得するのでこれよりも減らすべし
- クロール間隔
- 慣例的に1秒以上の間隔を設けるのが望ましい。例:国会図書館の運用するクローラー
- RSS・XMLなどのHTML以外に情報を取得する手段がある場合はそちらを使用する。
##4.3.2 robots.txtによるクローラーへの指示
- robots.txt
- Robots Exclusion Protocolという標準化された形式でクローラーへの指示(ディレクティブ)を記述する
- Pythonの標準ライブラリurllib.robotparserにはrobots.txtパースするためのRobotFile
Parserクラスがある - robots metaタグ
- HTMLのmetaタグにクローラーへの指示を記述する
<meta name="robots" content="<属性の値>">
- 属性の値にはページ内のリンクをたどることを許可しない
nofollow
,保存することを許可しないnoarchive
,検索エンジンにインデックスを許可しないnoindex
がある
いつもスクレイピングさせていただいているnetkeibaさんに関してはrobots.txtもmetaタグでの指示も特にないっぽい
##4.3.3 XMLサイトマップ
クローラーにクロールしてほしいURLを指示するXMLファイル
リンクを辿ってクローリングするより効率的
robots.txtのSitemapディレクティブに記述する
##4.3.4 連絡先の明示
クローラーが送信するリクエストのUser-AgentヘッダーにメールアドレスやURLなどの連絡先を記述することができる
##4.3.5 ステータスコードとエラー処理
クロール先に余計な負荷をかけないためにもエラー処理が重要
エラーが出たときにリトライする場合にはリトライ間隔を指数関数的に増やすなどの対策をする
エラー処理は定型的な記述が多いが、tenacityというライブラリを使うことで簡潔に記述することができる
#4.4 繰り返しの実行を前提とした設計
##4.4.1 更新されたデータだけを取得する
- HTTPのキャッシュポリシー
- HTTPサーバーはレスポンスにキャッシュに関するヘッダーをつけることでキャッシュポリシーを細かく指定することができる
- これらのヘッダーは「強いキャッシュ」「弱いキャッシュ」の2種類に分けられる。
- 強いキャッシュ→Cache-Control(キャッシュしてもよいか、など細かい指定)、Expires(コンテンツの有効期限)クライアント側はキャッシュが有効な間はリクエストを送らない。有効期限中はキャッシュされたレスポンスを使う。
- 弱いキャッシュ→Last-Modified(最終更新日),ETag(識別子)クライアント側は毎回リクエストは送るが、更新されていない場合はキャッシュされたレスポンスを使う。
- PythonではCacheControlというライブラリでキャッシュに関する処理を簡潔に扱える
pip install "CacheControl[filecache]"
##4.4.2 クロール先の変化を検知する
- 正規表現でバリデーションする
- JSON Schemaでバリデーションする
- Pythonではjsonschemaというライブラリを使うことで、JSON SchemaというJSON形式でバリデーションのルールを記述をすることができる
pip install jsonschema
- Pythonではjsonschemaというライブラリを使うことで、JSON SchemaというJSON形式でバリデーションのルールを記述をすることができる
こういった方法で変化が検知できた場合、メールで通知するなどしてクローラーを終了させる。
#4.5 まとめ
省略
#おわりに
やる気が出ずに投稿間隔が空いてしまいましたが、とりあえず生存確認がてら(?)の記事ということで