Pythonのrequestsで「Cannot allocate memory」エラーが出たときの対処法

※当サイトではアフィリエイト広告を利用しています

PythonでWebスクレイピングやデータ取得処理をしていると、requests.exceptions.ConnectionError が発生して処理が止まってしまうことがあります。

特に以下のようなエラーが出た場合:

requests.exceptions.ConnectionError: HTTPSConnectionPool(...): Max retries exceeded with url: ...
(Caused by NewConnectionError(...): Failed to establish a new connection: [Errno 12] Cannot allocate memory)

これは、接続のたびにメモリを消費しすぎて枯渇している状態です。


なぜこのエラーが出るのか?

主な原因は、requests.get() を繰り返し使っていることによって、毎回新しい接続が作られ、それが適切にクローズされずにメモリを食い続けることにあります。

例えば、以下のようにページごとにリクエストしていた場合:

import requests

for page in range(1, 100):
url = f"https://example.com/data?page={page}"
response = requests.get(url)
# 処理

このような書き方では、毎回接続が新しく確立されてしまい、長時間ループすると最終的に Cannot allocate memory エラーにつながる可能性があります。


解決策:requests.Session() を使う

この問題を解決するには、requests.Session() を使って、接続を再利用することが有効です。

import requests
import time

with requests.Session() as session:
for page in range(1, 100):
url = f"https://example.com/data?page={page}"
try:
response = session.get(url)
print(response.status_code)
time.sleep(1) # 過負荷防止のために少し待機
except Exception as e:
print(f"エラー発生: {e}")

Session() を使うことで、同一ホストへの接続が効率よく再利用され、メモリの使用量も安定します。スリープを入れることで、DoSと見なされるリスクも下げられます。


Macでメモリ使用状況を確認するには

エラーが発生したときは、Macのターミナルで以下のコマンドを使ってメモリ状況をチェックできます。

top -o mem

または、スワップの状況なども含めて確認したい場合は:

vm_stat

Pages free が極端に少ない、Swapouts が増えている、といった状況であれば、明らかにメモリが不足しています。


まとめ

  • requests.get() を連続で使うとメモリ不足になることがある
  • requests.Session() を使えば接続の再利用ができ、メモリ効率が良くなる
  • エラーが出たら、topvm_stat でメモリ状況を確認
  • スクレイピング処理には time.sleep() を適宜入れるのも大切

スクレイピング処理は長時間回すことも多いため、ちょっとした工夫で安定性が大きく向上します。
エラーで悩んだときは、まず Session() を試してみるのがおすすめです。

コメント