has - urllib python install
¿Cómo saber si urllib.urlretrieve tiene éxito? (8)
urllib.urlretrieve
devuelve silenciosamente incluso si el archivo no existe en el servidor http remoto, solo guarda una página html en el archivo nombrado. Por ejemplo:
urllib.urlretrieve(''http://google.com/abc.jpg'', ''abc.jpg'')
simplemente regresa silenciosamente, incluso si abc.jpg no existe en el servidor google.com, el abc.jpg
generado no es un archivo jpg válido, en realidad es una página html. Supongo que los encabezados devueltos (una instancia de httplib.HTTPMessage) se pueden usar para decir realmente si la recuperación tiene éxito o no, pero no puedo encontrar ningún documento para httplib.HTTPMessage
.
¿Alguien puede proporcionar información sobre este problema?
:) Mi primera publicación en , ha sido un acecho durante años. :)
Tristemente, dir (urllib.urlretrieve) es deficiente en información útil. Así que de este hilo hasta el momento intenté escribir esto:
a,b = urllib.urlretrieve(imgURL, saveTo)
print "A:", a
print "B:", b
que produjo esto:
A: /home/myuser/targetfile.gif
B: Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Cache-Control: max-age=604800
Content-Type: image/gif
Date: Mon, 07 Mar 2016 23:37:34 GMT
Etag: "4e1a5d9cc0857184df682518b9b0da33"
Last-Modified: Sun, 06 Mar 2016 21:16:48 GMT
Server: ECS (hnd/057A)
Timing-Allow-Origin: *
X-Cache: HIT
Content-Length: 27027
Connection: close
Creo que uno puede verificar:
if b.Content-Length > 0:
Mi siguiente paso es probar un escenario donde falla la recuperación ...
Considere usar urllib2
si es posible en su caso. Es más avanzado y fácil de usar que urllib
.
Puede detectar cualquier error HTTP fácilmente:
>>> import urllib2
>>> resp = urllib2.urlopen("http://google.com/abc.jpg")
Traceback (most recent call last):
<<MANY LINES SKIPPED>>
urllib2.HTTPError: HTTP Error 404: Not Found
resp
es en realidad HTTPResponse
objeto HTTPResponse
que puede hacer muchas cosas útiles con:
>>> resp = urllib2.urlopen("http://google.com/")
>>> resp.code
200
>>> resp.headers["content-type"]
''text/html; charset=windows-1251''
>>> resp.read()
"<<ACTUAL HTML>>"
De acuerdo con la documentación, está undocumented
para tener acceso al mensaje, parece que haces algo como:
a, b=urllib.urlretrieve(''http://google.com/abc.jpg'', r''c:/abc.jpg'')
b es la instancia del mensaje
Desde que aprendí que Python siempre es útil usar la habilidad de Python para ser introspectivo cuando escribo
dir(b)
Veo muchos métodos o funciones con los que jugar
Y luego comencé a hacer cosas con b
por ejemplo
b.items()
Enumera muchas cosas interesantes, sospecho que jugar con estas cosas te permitirá obtener el atributo que deseas manipular.
Lo siento, esta es la respuesta de un principiante, pero estoy tratando de dominar cómo usar las habilidades de introspección para mejorar mi aprendizaje y sus preguntas simplemente aparecieron.
Bueno, probé algo interesante relacionado con esto, me preguntaba si podría obtener automáticamente el resultado de cada una de las cosas que aparecían en el directorio que no necesitaban parámetros, así que escribí:
needparam=[]
for each in dir(b):
x=''b.''+each+''()''
try:
eval(x)
print x
except:
needparam.append(x)
Lo mantengo simple:
# Simple downloading with progress indicator, by Cees Timmerman, 16mar12.
import urllib2
remote = r"http://some.big.file"
local = r"c:/downloads/bigfile.dat"
u = urllib2.urlopen(remote)
h = u.info()
totalSize = int(h["Content-Length"])
print "Downloading %s bytes..." % totalSize,
fp = open(local, ''wb'')
blockSize = 8192 #100000 # urllib.urlretrieve uses 8192
count = 0
while True:
chunk = u.read(blockSize)
if not chunk: break
fp.write(chunk)
count += 1
if totalSize > 0:
percent = int(count * blockSize * 100 / totalSize)
if percent > 100: percent = 100
print "%2d%%" % percent,
if percent < 100:
print "/b/b/b/b/b", # Erase "NN% "
else:
print "Done."
fp.flush()
fp.close()
if not totalSize:
print
Puede crear un nuevo URLopener (heredar de FancyURLopener) y lanzar excepciones o manejar errores de la forma que desee. Desafortunadamente, FancyURLopener ignora 404 y otros errores. Ver esta pregunta:
Resultados contra otro servidor / sitio web: lo que aparece en "B" es un poco aleatorio, pero se pueden probar ciertos valores:
A: get_good.jpg
B: Date: Tue, 08 Mar 2016 00:44:19 GMT
Server: Apache
Last-Modified: Sat, 02 Jan 2016 09:17:21 GMT
ETag: "524cf9-18afe-528565aef9ef0"
Accept-Ranges: bytes
Content-Length: 101118
Connection: close
Content-Type: image/jpeg
A: get_bad.jpg
B: Date: Tue, 08 Mar 2016 00:44:20 GMT
Server: Apache
Content-Length: 1363
X-Frame-Options: deny
Connection: close
Content-Type: text/html
En el caso ''malo'' (archivo de imagen no existente), "B" recuperó una pequeña porción del código HTML (Googlebot?) Y lo guardó como destino, por lo tanto, Content-Length de 1363 bytes.
Terminé con mi propia implementación de retrieve
, con la ayuda de pycurl
admite más protocolos que urllib / urllib2, espero que pueda ayudar a otras personas.
import tempfile
import pycurl
import os
def get_filename_parts_from_url(url):
fullname = url.split(''/'')[-1].split(''#'')[0].split(''?'')[0]
t = list(os.path.splitext(fullname))
if t[1]:
t[1] = t[1][1:]
return t
def retrieve(url, filename=None):
if not filename:
garbage, suffix = get_filename_parts_from_url(url)
f = tempfile.NamedTemporaryFile(suffix = ''.'' + suffix, delete=False)
filename = f.name
else:
f = open(filename, ''wb'')
c = pycurl.Curl()
c.setopt(pycurl.URL, str(url))
c.setopt(pycurl.WRITEFUNCTION, f.write)
try:
c.perform()
except:
filename = None
finally:
c.close()
f.close()
return filename
class MyURLopener(urllib.FancyURLopener):
http_error_default = urllib.URLopener.http_error_default
url = "http://page404.com"
filename = "download.txt"
def reporthook(blockcount, blocksize, totalsize):
pass
...
try:
(f,headers)=MyURLopener().retrieve(url, filename, reporthook)
except Exception, e:
print e