LoginSignup
5

More than 3 years have passed since last update.

PythonでHTTPキャッシュを使う

Last updated at Posted at 2020-06-07

クローラー作成の時には、繰り返しの実行を念頭におくと思います。
そこで、クローラー先にサイトのキャッシュが気になります。

キャッシュがかかった状態で再度、実行しても同じページをみていて取得できるデータが同じです。

今回は、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キャッシュを使う

import requests
from cachecontrol import CacheControl 
from cachecontrol.caches import FileCache

session = 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回目からはキャッシュされている内容が返ってきます。

参考

Pythonクローリング&スクレイピング

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5