Tengo un script que me gustaría seguir usando, pero parece que tengo que encontrar alguna solución para un error en Python 3, o rebajar de nuevo a 2.6, y tener que degradar otros scripts también ..¿Cómo descargar un archivo a través de http con autorización en python 3.0, trabajando alrededor de los errores?
Esperemos que alguien aquí ya haya logrado encontrar una solución alternativa.
El problema es que debido a los nuevos cambios en Python 3.0 con respecto a los bytes y las cadenas, no todo el código de la biblioteca es aparentemente probado.
Tengo un script que descarga una página de un servidor web. Esta secuencia de comandos pasó un nombre de usuario y una contraseña como parte de la url en Python 2.6, pero en Python 3.0, esto ya no funciona.
Por ejemplo, esto:
import urllib.request;
url = "http://username:[email protected]/file";
urllib.request.urlretrieve(url, "temp.dat");
falla con esta excepción:
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
Aparentemente, base64-codificación necesita ahora bytes en y emite una cadena, y por lo tanto urlretrieve (o algo de código en él) que construye una cadena de nombre de usuario: contraseña e intenta codificar64 a base de esto para una autorización simple, falla.
Si en lugar de tratar de usar urlopen, así:
import urllib.request;
url = "http://username:[email protected]/file";
f = urllib.request.urlopen(url);
contents = f.read();
Entonces se produce un error con esta excepción:
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]'
Al parecer, el análisis de URL en esta "biblioteca siguiente de recuperación url gen" doesn No sé qué hacer con el nombre de usuario y las contraseñas en la url.
¿Qué otras opciones tengo?
¿Quiso publicar esa contraseña? De lo contrario, sugiero eliminar la respuesta y publicar una nueva con datos ficticios allí. Gracias por la respuesta, parece prometedor. –
Directo desde los documentos de Python: P –
Klem probablemente está bastante molesto si esa es su verdadera contraseña :) –