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()を使えば接続の再利用ができ、メモリ効率が良くなる- エラーが出たら、
topやvm_statでメモリ状況を確認 - スクレイピング処理には
time.sleep()を適宜入れるのも大切
スクレイピング処理は長時間回すことも多いため、ちょっとした工夫で安定性が大きく向上します。
エラーで悩んだときは、まず Session() を試してみるのがおすすめです。


コメント