Python 3.6におけるgrequestsのエラー

#grequests#Python#requests

以前「greqeuestsでHTTPリクエストを非同期に処理できる、便利!」と記事に書きましたが、今回エラーにあったのでまとめます。 http://roy29fuku.com/web/summereye/speed-up/#grequestsHTTP

発生時の環境

  • Mac
  • Python 3.6.3
  • grequests 0.3.0
  • requests 2.18.4
  • gevent 1.2.2

エラー内容 requestsでエラーが発生

上記環境下で以下のようにrequests, grequestsをインポートしてrequestsを使うとエラーが発生しました。

import requests
import grequests
url = 'https://www.google.co.jp/'
requests.get(url)

  これによりRecursionError: maximum recursion depth exceededが発生します。 [Previous line repeated 323 more times]ともありますが、Pythonが許容する再起処理の回数を超えたことによりプログラムが停止したようです。   ちなみに、この値はsys.getrecursionlimit()によって設定されており、デフォルトでは1000回です。 以下のように回数制限を変更することが可能ですが、今回の問題を解決しません。

import sys
sys.setrecursionlimit(1500)

解決方法

githubにissueが立てられていました。

  grequestsを先に読み込んでからrequestsを読み込むことで回避できるとのこと。 確認。

おまけ

grequestsインポートした後にreqeuestsを使おうと思ったらエラーが出たので驚きました。 因果関係がわかりにくかったので結構詰まりました。やっぱり公式を確認するのが大事ですね。   grequestsは、作者がGithubで以下のように別のライブラリを推奨しています。

Note: You should probably use requests-threads or requests-futures instead.

kennethreitz/grequests: Requests + Gevent

  今回の問題も根本的な解決には至っていないみたいで、今後のアップデートも活発に行われないような感じがします。 Pythonの新しいバージョンを使う場合はライブラリのアップデート頻度などに気をつけようと思います。 requests-threads、requests-futures insteadも時間があるときに確認したいと思います。   余談ですが、クローラー書いてて再起処理したらリンクがループしてて非常にハマりました。 クローリング用のフレームワークも試してみようと思いました。

参考