[解決済み] Python: Pythonオブジェクトの呼び出し中に再帰の最大深度を超えた
質問
私は約5Mページ(URL IDを増加させることによって)実行する必要があり、その後、私が必要とする情報を含むページをパースするクローラを構築しています。
200KのURLで実行するアルゴリズムを使用し、良い結果と悪い結果を保存した後、私は多くの時間を無駄にしていることに気づきました。私は、次の有効なURLを確認するために使用することができますいくつかの戻りsubstrahendsがあることを確認することができました。
は、非常に高速にサブトラヘンドを見ることができます(少数の最初の "良い ID" の少し例) - 。
510000011 # +8
510000029 # +18
510000037 # +8
510000045 # +8
510000052 # +7
510000060 # +8
510000078 # +18
510000086 # +8
510000094 # +8
510000102 # +8
510000110 # etc'
510000128
510000136
510000144
510000151
510000169
510000177
510000185
510000193
510000201
200KのURLをクロールして14Kの結果しか得られなかったので、時間を無駄にしていると思い、最適化する必要があると思いました。
これがその関数です。
def checkNextID(ID):
global numOfRuns, curRes, lastResult
while ID < lastResult:
try:
numOfRuns += 1
if numOfRuns % 10 == 0:
time.sleep(3) # sleep every 10 iterations
if isValid(ID + 8):
parseHTML(curRes)
checkNextID(ID + 8)
return 0
if isValid(ID + 18):
parseHTML(curRes)
checkNextID(ID + 18)
return 0
if isValid(ID + 7):
parseHTML(curRes)
checkNextID(ID + 7)
return 0
if isValid(ID + 17):
parseHTML(curRes)
checkNextID(ID + 17)
return 0
if isValid(ID+6):
parseHTML(curRes)
checkNextID(ID + 6)
return 0
if isValid(ID + 16):
parseHTML(curRes)
checkNextID(ID + 16)
return 0
else:
checkNextID(ID + 1)
return 0
except Exception, e:
print "somethin went wrong: " + str(e)
は基本的に何をするかというと、-checkNextID(ID)は、データから8を引いたものを含む私が知っている最初のidを取得するため、最初の反復は最初の "if isValid" 節に一致します(isValid(ID + 8)は真を返す)。
最終結果 は最後に判明したURL IDを保存する変数で、numOfRunsが0になるまで実行します。
isValid() は、ID + 末尾の 1 つを取得し、url が必要なものを含んでいれば True を返し、url のスープオブジェクトをグローバル変数に保存する関数です。 curRes '、urlが必要なデータを含んでいない場合はFalseを返します。
パースHTML は、スープオブジェクト (curRes) を取得し、必要なデータをパースして、そのデータを csv に保存して、True を返す関数です。
isValid()がTrueを返したら、parseHTML()を呼び出し、次のID+subrahendsをチェックします(checkNextID(ID+subrahends)を呼び出して、どれも私が探しているものを返さない場合は1を増やして、次の有効なurlが見つかるまで再度チェックします)。
残りのコードを見ることができます ここで
を実行した後、950~の良好な結果が得られたのですが、突然例外が発生しました。
を呼び出している間に再帰的深度の最大値を超えてしまいました。 Pythonオブジェクト"。
WireSharkで、scriptがid - 510009541(私は510000003でスクリプトを開始しました)で止まっているのを確認しました。私がエラーに気づいて停止するまで、スクリプトは数回そのIDでURLを取得しようとしました。
同じ結果を得たのに、古いスクリプトより25倍から40倍も速く、HTTPリクエストも少なく、非常に正確で、1000の良い結果に対してたった1つの結果しか見逃していない、これは私にとっては発見です。
スタック制限について読みましたが、私がPythonで実装しようとしているアルゴリズムには解決策があるはずです(私は以前の アルゴリズム" このままでは終われません)。
ありがとうございました。
解決方法は?
これは、再帰をループに変える。
def checkNextID(ID):
global numOfRuns, curRes, lastResult
while ID < lastResult:
try:
numOfRuns += 1
if numOfRuns % 10 == 0:
time.sleep(3) # sleep every 10 iterations
if isValid(ID + 8):
parseHTML(curRes)
ID = ID + 8
elif isValid(ID + 18):
parseHTML(curRes)
ID = ID + 18
elif isValid(ID + 7):
parseHTML(curRes)
ID = ID + 7
elif isValid(ID + 17):
parseHTML(curRes)
ID = ID + 17
elif isValid(ID+6):
parseHTML(curRes)
ID = ID + 6
elif isValid(ID + 16):
parseHTML(curRes)
ID = ID + 16
else:
ID = ID + 1
except Exception, e:
print "somethin went wrong: " + str(e)
関連
-
Pythonコンテナのための組み込み汎用関数操作
-
[解決済み] Pythonで、あるオブジェクトが反復可能かどうかを判断するにはどうしたらいいですか?
-
[解決済み] Pythonでオブジェクトが属性を持つかどうかを知る方法
-
[解決済み] Pythonのクラスはなぜオブジェクトを継承するのですか?
-
[解決済み] Pythonでnullオブジェクトを参照する
-
[解決済み] 億の相対的輸入
-
[解決済み] 2次元アレイにおけるピーク検出
-
[解決済み] Pythonでタイムゾーンを意識したdatetimeオブジェクトを作るには?
-
[解決済み] Pythonの最大再帰深度とその増やし方とは?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
pythonを使ったオフィス自動化コード例
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
PyQt5はユーザーログインGUIインターフェースとログイン後のジャンプを実装しています。
-
Pythonの画像ファイル処理用ライブラリ「Pillow」(グラフィックの詳細)
-
[解決済み】お使いのCPUは、このTensorFlowバイナリが使用するようにコンパイルされていない命令をサポートしています。AVX AVX2
-
[解決済み】socket.error: [Errno 48] アドレスはすでに使用中です。
-
[解決済み】TypeError: re.findall()でバイトのようなオブジェクトに文字列パターンを使用することはできません。)
-
[解決済み】終了コード -1073741515 (0xC0000135)でプロセス終了)
-
[解決済み】TypeErrorを取得しました。エントリを持つ子テーブルの後に親テーブルを追加しようとすると、 __init__() missing 1 required positional argument: 'on_delete'
-
[解決済み] リスト内のすべての要素が同一であるかどうかをチェックする