引き続き使用したいスクリプトがありますが、Python 3 のバグの回避策を見つけるか、2.6 にダウングレードして、他のスクリプトもダウングレードする必要があるようです...
うまくいけば、ここの誰かがすでに回避策を見つけていることを願っています。
問題は、バイトと文字列に関する Python 3.0 の新しい変更により、明らかにすべてのライブラリ コードがテストされていないことです。
Web サーバーからページをダウンロードするスクリプトがあります。このスクリプトは、Python 2.6 の URL の一部としてユーザー名とパスワードを渡しましたが、Python 3.0 ではこれが機能しなくなりました。
たとえば、これは次のとおりです。
import urllib.request;
url = "http://username:password@server/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 エンコーディングにはバイトが必要であり、文字列を出力するため、username:password の文字列を構築し、単純な認証のためにこれを base64 エンコードしようとする urlretrieve (またはその中のコード) は失敗します。
代わりに urlopen を使用しようとすると、次のようになります。
import urllib.request;
url = "http://username:password@server/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: 'password@server'
どうやら、この「次世代 URL 検索ライブラリ」の URL 解析では、URL 内のユーザー名とパスワードをどう処理すればよいかわかりません。
他にどのような選択肢がありますか?