1. 程式人生 > >關於報urllib2.HTTPError: HTTP Error 401: Unauthorized錯誤問題

關於報urllib2.HTTPError: HTTP Error 401: Unauthorized錯誤問題

報錯資訊:

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    callInfo = server.methods['getTemp']
  File "SOAPpy\Client.py", line 472, in __call__
    return self.__r_call(*args, **kw)
  File "SOAPpy\Client.py", line 494, in __r_call
    self.__hd, self.__ma)
  File "SOAPpy\Client.py", line 365, in __call
    config = self.config)
  File "SOAPpy\Client.py", line 265, in call
    raise HTTPError(code, msg)

HTTPError: <HTTPError 401 Unauthorized>

401意思就是未認證, 需要你登陸, 這個網站只是利用了401狀態碼, 並沒有真的做Basic/Digest認證, 頁面還是隨之返回的, 不過文章內容被截斷了, 頁面裡也有說明, 抓取法如下:

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import urllib2
import zlib

headers = {
                        "User-Agent":"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6",
          }
try:
        req = urllib2.Request("http://www.nature.com/onc/journal/v29/n35/full/onc2010241a.html", headers = headers)
        res = urllib2.urlopen(req)
except urllib2.HTTPError as http_error:
        print zlib.decompress(http_error.read(), 30)

先瀏覽器訪問了一下這個網址, 發現401錯誤但頁面正常顯示, 看Response header發現沒有401相關的tag, 但content裡是有頁面的.

所以, 就有了上面的程式碼, 也就是你可以看到你貼的錯誤是HttpError異常, 去Python manual裡翻一翻urlib2的幫助, 就可以找到這個異常以及誰丟擲此異常, 前提是你先要明白urllib2的handler回撥機制, 每個註冊的handler都繼承base handler, 並且擁有所有回撥介面(可能沒有覆寫, 也就是不作用), 你可以很快的閱讀發現隨著httperror異常丟擲的物件擁有urlopen返回值一樣的介面, 也就是read, 用它就可以讀取content了.

至於zlib就是解壓gzip格式資料, 你可以manual看zlib相關內容(我是做C的, zlib用的多), 之所以要解壓是因為我注意到response header裡說明了編碼方式為gzip, 而更健壯的程式應該是捕獲異常後判斷http_error物件裡的header字典內的content-encoding欄位是什麼格式.