クローラー作成の時には、繰り返しの実行を念頭におくと思います。
そこで、クローラー先にサイトのキャッシュが気になります。
キャッシュがかかった状態で再度、実行しても同じページをみていて取得できるデータが同じです。
今回は、PythonにおけるHTTPキャッシュについてまとめたいと思います。
HTTPキャッシュ
HTTPキャッシュは、RFC7234で定められている。
HTTPサーバはレスポンスにキャッシュに関するヘッダーをつけることで、HTTPクライアントに足しいてコンテンツのキャッシュ方針を指示できる。
HTTPヘッダー | Right align |
---|---|
Cache-Control | コンテンツをキャッシュしても良いかなど、キャッシュ方針を細かく指示する |
Expires | コンテンツの有効期限を示す |
Etag | コンテンツの識別子を表す。コンテンツが変わるとEtagの値も変わる |
Last-Modified | コンテンツの最新更新日時を表す |
Pragma | Cache-Controlと似たものだったが、現在では後方互換のためだけに残されている |
Vary | 値に含まれるリクエストヘッダーの値が変わるとサーバーが返すレスポンスも変わることを表す |
強いキャッシュ
- Cache-Control
- Expires
は、クライアントは一度レスポンスをキャッシュすると、有効期限が切れるまではリクエストを送らず、キャッシュされたレスポンスを使う。
弱いキャッシュ
- Last-Modified
- Etag
は、クライアントは一度レスポンスをキャッシュすると、次回から条件付きのリクエストを送り、サーバーは更新がない場合は304というステータスコードで空のレスポンスボディを返す。
PythonでHTTPキャッシュを使う
importrequestsfromcachecontrolimportCacheControlfromcachecontrol.cachesimportFileCachesession=requests.Session()# sessionをラップしたcached_sessionを作る。
# キャッシュはファイルとして .webcache ディレクトリ内に保存する。
cached_session=CacheControl(session,cache=FileCache('.webcache'))response=cached_session.get('URL')# response.from_cache属性でキャッシュから取得されたレスポンスかどうかを取得できる。
print(f'from_cache: {response.from_cache}')print(f'status_code: {response.status_code}')
2回目からはキャッシュされている内容が返ってきます。