2008-12-27 61 views
7

我有一個腳本,我想繼續使用,但它看起來像我要麼找到一些解決方案,在Python 3中的錯誤,或降級到2.6,從而不得不降級其他腳本以及..如何使用python 3.0的授權通過http下載文件,解決錯誤?

希望這裏有人已經設法找到解決方法。

問題是,由於Python 3.0中有關字節和字符串的新更改,並非所有庫代碼都顯然經過測試。

我有一個腳本,可以從網頁服務器下載頁面。這個腳本在Python 2.6中傳遞了一個用戶名和密碼作爲url的一部分,但是在Python 3.0中,這不再起作用。

例如,該:

import urllib.request; 
url = "http://username:[email protected]/file"; 
urllib.request.urlretrieve(url, "temp.dat"); 

失敗,出現此例外:

Traceback (most recent call last): 
    File "C:\Temp\test.py", line 5, in <module> 
    urllib.request.urlretrieve(url, "test.html"); 
    File "C:\Python30\lib\urllib\request.py", line 134, in urlretrieve 
    return _urlopener.retrieve(url, filename, reporthook, data) 
    File "C:\Python30\lib\urllib\request.py", line 1476, in retrieve 
    fp = self.open(url, data) 
    File "C:\Python30\lib\urllib\request.py", line 1444, in open 
    return getattr(self, name)(url) 
    File "C:\Python30\lib\urllib\request.py", line 1618, in open_http 
    return self._open_generic_http(http.client.HTTPConnection, url, data) 
    File "C:\Python30\lib\urllib\request.py", line 1576, in _open_generic_http 
    auth = base64.b64encode(user_passwd).strip() 
    File "C:\Python30\lib\base64.py", line 56, in b64encode 
    raise TypeError("expected bytes, not %s" % s.__class__.__name__) 
TypeError: expected bytes, not str 

顯然,BASE64編碼現在需要字節和輸出一個字符串,因此urlretrieve(或一些代碼在其中),它建立了一串用戶名:密碼,並試圖對這個簡單的授權進行base64編碼,失敗。

如果我不是嘗試使用的urlopen,像這樣:

import urllib.request; 
url = "http://username:[email protected]/file"; 
f = urllib.request.urlopen(url); 
contents = f.read(); 

那麼它失敗與此異常:

Traceback (most recent call last): 
    File "C:\Temp\test.py", line 5, in <module> 
    f = urllib.request.urlopen(url); 
    File "C:\Python30\lib\urllib\request.py", line 122, in urlopen 
    return _opener.open(url, data, timeout) 
    File "C:\Python30\lib\urllib\request.py", line 359, in open 
    response = self._open(req, data) 
    File "C:\Python30\lib\urllib\request.py", line 377, in _open 
    '_open', req) 
    File "C:\Python30\lib\urllib\request.py", line 337, in _call_chain 
    result = func(*args) 
    File "C:\Python30\lib\urllib\request.py", line 1082, in http_open 
    return self.do_open(http.client.HTTPConnection, req) 
    File "C:\Python30\lib\urllib\request.py", line 1051, in do_open 
    h = http_class(host, timeout=req.timeout) # will parse host:port 
    File "C:\Python30\lib\http\client.py", line 620, in __init__ 
    self._set_hostport(host, port) 
    File "C:\Python30\lib\http\client.py", line 632, in _set_hostport 
    raise InvalidURL("nonnumeric port: '%s'" % host[i+1:]) 
http.client.InvalidURL: nonnumeric port: '[email protected]' 

顯然,網址在這個「下一代URL檢索庫」解析沒有按不知道如何處理網址中的用戶名和密碼。

我還有其他選擇嗎?

回答

20

直接從Py3k文檔:http://docs.python.org/dev/py3k/library/urllib.request.html#examples

import urllib.request 
# Create an OpenerDirector with support for Basic HTTP Authentication... 
auth_handler = urllib.request.HTTPBasicAuthHandler() 
auth_handler.add_password(realm='PDQ Application', 
          uri='https://mahler:8092/site-updates.py', 
          user='klem', 
          passwd='kadidd!ehopper') 
opener = urllib.request.build_opener(auth_handler) 
# ...and install it globally so it can be used with urlopen. 
urllib.request.install_opener(opener) 
urllib.request.urlopen('http://www.example.com/login.html') 
+0

您是不是要發表該密碼?如果沒有,那麼我建議刪除答案並在那裏發佈一個新的虛擬數據。感謝您的答案,但看起來很有希望。 – 2008-12-27 23:11:23

0

我的建議是保持你的2 *分公司作爲生產分公司,直到你可以得到3.0的東西排序。

我將等待一段時間,然後再轉到Python 3.0。似乎很多人都在急於求成,但我只希望所有的東西都能被整理出來,並且還有一些體面的第三方庫。這可能需要一年的時間,可能需要18個月,但對於「升級」的壓力對我來說真的很低。

相關問題