1

私は例外処理の初心者です。mechanizeモジュールを使用して、いくつかのWebサイトをスクレイプしています。接続が遅く、リクエストがタイムアウトしたため、プログラムが頻繁に失敗します。各試行の間に30秒の遅延が発生した後、最大5回(たとえば、タイムアウト時に)Webサイトを再試行できるようにしたいと思います。

このstackoverflowの回答を見て、さまざまな例外を処理する方法を確認できます。また、(非常に不器用に見えますが)試行/例外をwhileループ内に配置して、5回の試行を制御する方法もわかります...しかし、ループから抜け出す方法、つまり接続時に「続行」する方法がわかりません。は成功し、例外はスローされていません。

from mechanize import Browser
import time

b = Browser()
tried=0
while tried < 5:
  try:
    r=b.open('http://www.google.com/foobar')
  except (mechanize.HTTPError,mechanize.URLError) as e:
    if isinstance(e,mechanize.HTTPError):
      print e.code
      tried += 1
      sleep(30)
      if tried > 4:
        exit()
    else:
      print e.reason.args
      tried += 1
      sleep(30)
      if tried > 4:
        exit()

print "How can I get to here after the first successful b.open() attempt????"

(1)正常に開いたときにループから抜け出す方法、および(2)ブロック全体を不器用でなく/よりエレガントにする方法についてアドバイスをいただければ幸いです。

4

3 に答える 3

4

breakあなたの最初の質問は:で行うことができます

while tried < 5:
  try:
    r=b.open('http://www.google.com/foobar')
    break
  except #etc...

ただし、本当の問題は、本当にやりたいことです。これは「スパゲッティコード」と呼ばれるものです。プログラムを介して実行をグラフ化しようとすると、スパゲッティのプレートのように見えます。

あなたが抱えている本当の(私見の)問題は、whileループを終了するためのロジックに欠陥があることです。何度か試行した後に停止しようとするのではなく(とにかくすでに終了しているために発生しない状態)、接続が確立されるまでループします。

#imports etc

tried=0
connected = False
while not Connected:
    try:
        r = b.open('http://www.google.com/foobar')
        connected = true # if line above fails, this is never executed
    except mechanize.HTTPError as e:
        print e.code            
        tried += 1        
        if tried > 4:
            exit() 
        sleep(30)

    except mechanize.URLError as e:
        print e.reason.args            
        tried += 1
        if tried > 4:
            exit()        
        sleep(30)

 #Do stuff
于 2013-03-25T11:42:04.470 に答える
2

どちらの場合も、ブロック以外で繰り返す必要はありません。

from mechanize import Browser
import time

b = Browser()
tried=0
while True:
  try:
    r=b.open('http://www.google.com/foobar')
  except (mechanize.HTTPError,mechanize.URLError) as e:
      tried += 1
    if isinstance(e,mechanize.HTTPError):
      print e.code
    else:
      print e.reason.args
    if tried > 4:
      exit()
    sleep(30)
    continue
  break

while not r:また、返品内容によってはご利用いただける場合がございBrowser.openます。

編集:roadierichはよりエレガントな方法を示しました

try:
  doSomething()
  break
except:
  ...

エラーが例外ブロックにスキップするためです。

于 2013-03-25T11:32:40.157 に答える
1

最初の質問では、ループから抜け出す「break」キーワードが必要です。

2番目の質問では、さまざまな種類の例外に対して、1つの「try」に対して複数の「except」句を含めることができます。これにより、isinstance()チェックが置き換えられ、コードがよりクリーンになります。

于 2013-03-25T11:28:14.983 に答える