2016-05-01 13 views
1

私は現在、Ryan MitchellのPythonによるWeb Scrapingを行っています。彼はエラー処理について語っ第一章では、彼は言う:urlopen not returningなしURLが誤って入力されたときにオブジェクト

サーバーが全く見つからない場合(たとえば、サイトがダウンした、またはURL を入力ミスしていた場合)、Noneオブジェクトを返しますurlopen

これをテストするため、次のスニペットを作成しました。このコードの第二の最後の行で

from urllib.request import urlopen 
from urllib.error import HTTPError 
from bs4 import BeautifulSoup as bs 

def getTitle(url): 

    try: 
     html = urlopen(url).read() 
    except HTTPError: 
     return None 

    try: 
     bsObj = bs(html) 
    except AttributeError: 
     return None 
    return bsObj 

title = getTitle('http://www.wunderlst.com') 
print(title) 

、私は意図的に(実際のURLがhttp://www.wunderlist.comある)URL名を誤って入力しています。私はNoneが私の画面に印刷されることを望んだ。しかし、私はエラーの長いリストを取得します。以下は、私は、エラーメッセージの最後の部分を与えている:

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "ex4.py", line 18, in <module> 
    title = getTitle('http://www.wunderlst.com') 
    File "ex4.py", line 8, in getTitle 
    html = urlopen(url).read() 
    File "/usr/lib/python3.4/urllib/request.py", line 161, in urlopen 
    return opener.open(url, data, timeout) 
    File "/usr/lib/python3.4/urllib/request.py", line 463, in open 
    response = self._open(req, data) 
    File "/usr/lib/python3.4/urllib/request.py", line 481, in _open 
    '_open', req) 
    File "/usr/lib/python3.4/urllib/request.py", line 441, in _call_chain 
    result = func(*args) 
    File "/usr/lib/python3.4/urllib/request.py", line 1210, in http_open 
    return self.do_open(http.client.HTTPConnection, req) 
    File "/usr/lib/python3.4/urllib/request.py", line 1184, in do_open 
    raise URLError(err) 
urllib.error.URLError: <urlopen error [Errno -2] Name or service not known> 

、私はURLの名前を訂正しますが、例えば、ウェブサイトの前にいくつか存在しないページを作成する場合:

title = getTitle('http://www.wunderlist.com/something') 

その後私はNoneを画面に印刷します。私は本当にこれについて混乱しています。実際に何が起きているのか誰でも親切に説明できますか?前もって感謝します。

答えて

1

私はこの問題は、あなただけHTTPErrorを引く(とNoneを返していない)だと思います。 URLErrorの例外を処理する/キャッチするようにしてください。


from urllib.error import HTTPError, URLError
from urllib.error import HTTPError
を交換してください。

は、これはあなたが(どちらの場合もNoneを返す)望んでいた動作が得られます
except (HTTPError, URLError):


except HTTPError:
を交換してください。 しかし、これらのエラーを別々に扱うことをお勧めします(最初のtryブロックを別の方法に移動し、エラーの発生を防ぐなど)。

+0

これは便利です。なぜこの本に「URLError」は言及されていないのか分かりません。 – Peaceful

0

あなたが参照している本/記事が間違っているか古いです。 urllib documentationを読むことができます

接続できない場合、IOError例外が発生します。

ホスト名を解決できない場合は、明らかに接続ができないため、ドキュメントに従ってIOErrorを発行する必要があります。 URLErrorは古いPythonsのIOErrorのサブクラスです。urllibの新しいバージョンでは、わかりやすく見えるものからurlopenという機能を持っていないようです。


コメントに記載されているとおり、私はライブラリが間違っています(urllib.requestの代わりにurllib)。あなたは同様の行があります。

エラー時にURLErrorを発生させます。

そこに。恐らく404のようなHTTPエラーはurlopenのエラーとはみなされません。なぜなら、パスが間違っていれば例外は発生しませんが、ホスト名を解決できないとエラーになるからです。

+1

これは明らかにPython 3で、インポートとトレースバックからです。 [docs](https://docs.python.org/3/library/urllib.error.html#urllib.error.URLError)の状態で、urllib.request.urlopenはURLErrorを発生させます。これはエラーに表示されているものですメッセージ。 –

+0

@Cubic:あなたはPython2のドキュメントを参照していると思います。あなたの言うことが私の質問に答えるかどうかは分かりません。 – Peaceful

+0

@SnehalShekatkar Python3のドキュメントは似ていますが、例外がスローされる時期はあまり詳しくは書かれていません。それで更新されました。 – Cubic

0

ネットワーク接続がない(指定されたサーバーへのルートがない)ため、または指定したサーバーが存在しないため、URLErrorが発生することがよくあります。

'http://www.wunderlst.com'が存在しませんなぜエラーが発生するのですか?

詳細を確認するには、次のリンクをクリックしてください。

https://docs.python.org/3.1/howto/urllib2.html#handling-exceptions

関連する問題