CodeGym /コース /Python SELF JA /データの保存とキャッシュ

データの保存とキャッシュ

Python SELF JA
レベル 34 , レッスン 4
使用可能

1. なぜキャッシュが必要?

さて、みんな、Webスクレイピングの中でも特に面白い部分、データのキャッシュについて触れていこう!なんでキャッシュなのかって?スクリプトの実行で自分の「最速記録」を作るようなものだから!わかりやすく説明するから、リラックスして聞いてね。

想像してみて:あるウェブサイトをスクレイピングして必要なデータを取得したとする。そして翌日、それを更新したいときにまた無限ループのようなリクエストを繰り返したいと思う?いやいや、それを避けてデータをキャッシュして保存しちゃおう。

キャッシュのメリット:

  • スピード: キャッシュされたデータはサーバーから再取得するよりもすぐに利用できる。例えるなら、お気に入りのケーキが冷蔵庫にあると思えば、再びパン屋に行かなくてもすぐ楽しめる!
  • 節約: サーバーに無駄なリクエストを送らずに済むし、自分のインターネットトラフィックも節約できる。お得だね!
  • 安定性: キャッシュは一時的な接続問題に対処するのにも役立つ。サイトが突然利用できなくなっても、データは手元にある。まるで予備のパラシュートを持っているような安心感。

2. データキャッシュの基本

キャッシュって何?

キャッシュは一時的なストレージで、以前取得したデータを再利用可能にするものだね。プログラミングでは、キャッシュを利用することで同じデータを再リクエストするのを防ぐことができる。自分専用のよく使う情報の図書館みたいなものだと思って。

キャッシュの種類:

  • メモリキャッシュ: 速いけど電源を切るとデータが消える。RAMみたいな感じ。
  • ファイルキャッシュ: ディスクにデータを保存するので、より耐久性がある。

3. Pythonで実践的なキャッシュ

Pythonでデータをキャッシュするには、requestsライブラリを使うことができる。ただし、requestsはデフォルトではキャッシュをサポートしていない。ここで助けてくれるのがrequests-cache。これにより、簡単にリクエストにキャッシュ機能を追加できる。

ライブラリのインストール

Bash

pip install requests-cache

キャッシュの設定

スクリプトにキャッシュを設定してみよう:

Python

import requests_cache

# SQLiteにキャッシュを設定
requests_cache.install_cache('demo_cache', expire_after=180)

import requests

# リクエストを送信
response = requests.get('https://jsonplaceholder.typicode.com/todos/1')

# どこから応答が来たか確認
print(f'From cache: {response.from_cache}')

# データを出力
print(response.json())

まず最初に、requests_cache.install_cacheを使ってキャッシュを設定するよ。これでキャッシュされたデータを保存するSQLiteデータベースが作成される。expire_afterというパラメータでキャッシュデータが削除されるまでの時間(秒)を指定する。ここでは3分間キャッシュする設定だよ。

キャッシュの特徴

このコードを再実行すると、response.from_cacheをチェックしてみて。返り値がTrueになったら、それは最初の3分間のキャッシュから応答が返ってきたということだよ。

キャッシュの削除

キャッシュを削除するのも簡単だよ: データベースのファイルを消すか、requests_cache.clear()メソッドを使ってキャッシュを全部クリアしちゃおう。

4. 進んだキャッシュの使い方

条件付きキャッシュ

時々、もっとコントロールされたキャッシュが必要なこともある。例えば、データがすでに古くなっている場合や、リクエストのパラメータが変わった場合などね。

そんなときは、requests-cacheを追加パラメータ付きで使ってみよう:

Python

requests_cache.install_cache('custom_cache',
             allowable_methods=['GET', 'POST'],
             allowable_codes=[200, 404],
             ignored_parameters=['timestamp'])

ここでは、GETPOSTメソッドだけをキャッシュし、さらにステータスコード200と404だけに対応させている。また、timestampパラメータを無視して、時間が異なるリクエストを別々に扱わないようにしているんだ。

Redisを使う

もっと強力なキャッシュ、例えば分散キャッシュをサポートしたい場合はredisを使おう。大規模データの世界で人気のインメモリーデータキャッシュシステムだよ。

作業手順:

  1. RedisとPythonライブラリをインストールする:
    Bash
    
    brew install redis  # macOSユーザー向け
    pip install redis
    
  2. プロジェクトにRedisを設定する:
    Python
    
    import redis
    import requests
    
    r = redis.Redis(host='localhost', port=6379, db=0)
    
    def get_cached_response(url):
        if r.get(url):
            return r.get(url).decode('utf-8')
        else:
            response = requests.get(url)
            r.setex(url, 3600, response.text)  # 1時間キャッシュ
            return response.text
    
    print(get_cached_response('https://jsonplaceholder.typicode.com/todos/1'))
    

この例では、Redisを使って応答を1時間保存している。キャッシュにデータがあるかチェックして、なければHTTPリクエストを実行しているだけだよ。

5. エラーハンドリング

キャッシュを使うとき、データベースが壊れていたり、キャッシュが更新されなかったりすることもある。そこで重要なのがログを取ることと、データを定期的にチェックすることなんだ。

ログを取るコード例:

Python

import logging

logging.basicConfig(level=logging.INFO)

try:
    response = get_cached_response('https://jsonplaceholder.typicode.com/todos/1')
    logging.info("キャッシュからデータを正常に取得しました")
except Exception as e:
    logging.error("データ取得中にエラー発生: %s", str(e))

まとめ

キャッシュはただのパフォーマンス向上ツールだけじゃなく、アプリケーションを信頼性が高く、ネットワークの一時的な問題やサーバーの過負荷に対しても強くする手段なんだ。requests-cacheredisのようなツールを使えば、リクエストを効率的に管理し、データを後の利用のために保存することができるよ。キャッシュの達人になって、スクリプトをリクエストの繰り返しで負担させないようにしよう!古いプログラマの言葉にあるように:「一度キャッシュするのは百回尋ねるよりマシ」。

1
タスク
Python SELF JA, レベル 34, レッスン 4
ロック未解除
データのキャッシュの基本
データのキャッシュの基本
2
タスク
Python SELF JA, レベル 34, レッスン 4
ロック未解除
パラメータ付きキャッシュ
パラメータ付きキャッシュ
3
タスク
Python SELF JA, レベル 34, レッスン 4
ロック未解除
Redisを使用したキャッシング
Redisを使用したキャッシング
4
タスク
Python SELF JA, レベル 34, レッスン 4
ロック未解除
キャッシュされたリクエストのエラー処理
キャッシュされたリクエストのエラー処理
1
アンケート/クイズ
パース制限の回避、レベル 34、レッスン 4
使用不可
パース制限の回避
パース制限の回避
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION