如何通过HTTP下载一个文件,授权在Python 3.0,周围的错误工作?
-
23-08-2019 - |
题
我有,我想继续使用脚本,但它看起来像我要么必须找到某种解决方法的错误在Python 3或降级到2.6,从而获得具有降级其他脚本也是如此。 ..
希望这里有人已经设法找到一个解决办法。
的问题是,由于在Python 3.0关于字节和字符串的新变化,并不是所有的库代码显然测试。
我有一个从web服务器downloades页面的脚本。这个脚本通过为在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编码现在需要以字节为单位,并输出一个字符串,因此urlretrieve(或一些代码在其中),其积聚的用户名的字符串:密码,并尝试为base64编码此为简单授权失败<。 / p>
如果我代替尝试使用的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检索库”解析不知道如何处理的用户名和密码的网址是什么做的。
还有什么其他选择,我必须?
解决方案
HTTP://文档
从Py3k文档直销。 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')
其他提示
我的建议是保持你的2 *分公司作为生产分公司,直到你可以得到3.0的东西排序。
我将在移动到Python 3.0之前等待一段时间。似乎有很多人在匆忙,但我只是想一切都整理出来,和第三方库体面的选择。这可能需要一年的时间,它可能需要18个月,但“升级”的压力是非常低的我。
不隶属于 StackOverflow