2011-05-23 25 views
4

Pythonで例外を正しく使用する方法はまだわかりません。私は完全に信頼できないデータを処理したい(変更しやすく、変更するとスクリプトが壊れる可能性がある)。 BeautifulSoupを使用してWebページを処理しています。ウェブサイトの作成者がウェブサイトに何らかの変更を加えた場合、一部の声明は例外を生じさせる可能性があります。のは、このコードの例を見てみましょう:例外を正しく処理する方法は?

data = urllib2.urlopen('http://example.com/somedocument.php').read() 
soup = BeautifulSoup(data, convertEntities="html") 

name = soup.find('td', text=re.compile(r'^Name$')).parent.nextSibling.string 

print name 

、そのウェブサイトの所有者は、ウェブサイトの内容を変更し、NamesにセルNameの名前を変更しますので、soup.find()が失敗した場合、例外AttributeError: 'NoneType' object has no attribute 'parent'が発生します。しかし、私は気にしない!私はいくつかのデータが利用できないことを期待しています。私はちょうど進むと、私は必要があるいくつかのデータがあるでしょう(もちろん利用できる持っているものの変数を使用したい、と彼らは利用できない場合、私は意志だけで終了し、私が思いついた

唯一のソリューションです:。

try: name = soup.find('td', text=re.compile(r'^Name$')).parent.nextSibling.string 
except AttributeError: name = False 
try: email = soup.find('td', text=re.compile(r'^Email$')).parent.nextSibling.string 
except AttributeError: email = False 
try: phone = soup.find('td', text=re.compile(r'^Phone$')).parent.nextSibling.string 
except AttributeError: phone = False 

if name: print name 
if email: print email 
if phone: print phone 

は、任意のより良い方法があるか、私はすべてのような文のためのtry-除いて作り続けなければならないそれがすべてで非常に見栄えしない

EDIT:?。私のための最善の解決策は、このようになります:

try: 
    print 'do some stuff here that may throw and exception' 
    print non_existant_variable_that_throws_an_exception_here 
    print 'and few more things to complete' 
except: 
    pass 

これは素晴らしいですが、passtryコードブロック内のものをスキップするので、and few more things to completeは決して印刷されません。パスのようなものがあったとしても、エラーを無視して実行を続けると、それは素晴らしいものになります。それは、すべてのエラーが合格ようになるあるようこの

try: 
    something() 
except AttributeError: 
    pass 

をしかし決してしない:あなたが例外を気にしない場合

+0

「最後に」を使用してください。 http://docs.python.org/tutorial/errors.html#defining-clean-up-actions – sdolan

+0

「パスでtryコードブロック内の項目をスキップします。」正しい。なぜ多くの文を 'try:'ブロックに入れるのですか? –

答えて

4

まず、あなたはそれを通過させることができ

try: 
    something() 
except Exception: 
    pass 

コードサンプルは、おそらく次のようなもので整理できます。

myDict = {} 

for item in ["Name", "Email", "Phone"]: 
    try: 
     myDict[item] = soup.find('td', text=re.compile(r'^%s$' % item)).parent.nextSibling.string 
    except Attribute 
     myDict[item] = "Not found" 

for item in ["Name", "Email", "Phone"]: 
    print "%s: %s" % (item, myDict[item]) 
+0

提案していただきありがとうございます。私が間違っていなければ、それは 'catch 'ではなく' except'でなければなりません。しかし、とにかく私の編集した質問を見てください。 2番目の提案については、私の例がdictを使用して、あなたが提案したようなことをするのが理にかなっていることを理解しています。しかし、それはほんの一例だった、私はそれが私の場合にはうまくいくとは思わない。私は、変数が利用可能かどうかをチェックし、それを使用していない場合は使用し、次に続けることをお勧めします。 – Gargauth

+0

ああ、うん、私は急いでいたと思う。 :-( – nakedfanatic

1

代わりにtry/finallyステートメントを使ってみましたか?

http://docs.python.org/tutorial/errors.html#defining-clean-up-actions

ドキュメントからの例:

>>> def divide(x, y): 
...  try: 
...   result = x/y 
...  except ZeroDivisionError: 
...   print "division by zero!" 
...  else: 
...   print "result is", result 
...  finally: 
...   print "executing finally clause" 

だから、あなたの例を使用する:

try: 
    do_some_stuff_here_that_may_throw_an_exception() 
except someError: 
    print "That didn't work!" 
else: 
    print variable_that_we_know_didnt_throw_an_exception_here 
finally: 
    print "finishing up stuff" 

は "最終的には" 常にexcecute意志、あなたは "を置くことができる場所、それはですので、仕上げ "というものです。

関連する問題