2016-05-01 12 views
1

我目前正在通過Ryan Mitchell的Python網頁抓取。在第一章中,當他談到處理錯誤,他說:當url被誤輸入時,urlopen不返回無對象

如果一切都沒有找到服務器(如果說,網站已經關閉,或者URL 輸入錯誤),urlopen返回None對象。

所以要測試這個,我創建了以下代碼片段。

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名稱(實際的URL是http://www.wunderlist.com)。我希望現在我能在屏幕上打印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現在捉(和返回無)。嘗試還處理/捕獲URLError例外。

更換
from urllib.error import HTTPError

from urllib.error import HTTPError, URLError

更換
except HTTPError:

except (HTTPError, URLError):

這會給你,你想(返回在這兩種情況下None)的行爲。 但我會建議分開處理這些錯誤(將第一個try塊移到另一個方法,停止錯誤等)。

+0

這很有用。我不明白爲什麼這本書沒有提到'URLError'。 – Peaceful

0

您所指的書/文章是錯誤的或過時的。在urllib documentation中,您可以讀取

如果無法建立連接,則會引發IOError異常。

如果主機名無法解析,顯然不能建立連接,因此必須根據文檔提出IOErrorURLError是較舊的Pythons中的IOError的子類,新版本的urllib似乎沒有我從粗略瀏覽中可以看出的urlopen函數。


正如在評論中提到的,我得到了錯誤的庫(urllib,而不是urllib.request);你會發現一條類似的線條說

引發錯誤的URLError。

雖然在那裏。據推測,像404錯誤這樣的HTTP錯誤並不被認爲是urlopen的錯誤,這就是爲什麼它在路徑錯誤時不會引發異常,但如果主機名無法解析則會引發錯誤。

+1

這顯然是Python 3,來自進口和追蹤;作爲[文檔](https://docs.python.org/3/library/urllib.error.html#urllib.error.URLError)狀態,urllib.request.urlopen引發了URLError,這是錯誤中顯示的內容信息。 –

+0

@Cubic:我認爲你指的是Python2文檔。我不確定你說的是否回答我的問題。 – Peaceful

+0

@SnehalShekatkar Python3文檔類似,但不太詳細說明它何時拋出異常。隨此更新。 – Cubic

相關問題