Wie kann man wissen, ob urllib.urlretrieve gelingt?
-
13-09-2019 - |
Frage
urllib.urlretrieve
kehrt still, auch wenn die Datei auf dem Remote-HTTP-Server nicht vorhanden ist, es spart nur eine HTML-Seite in die angegebene Datei. Zum Beispiel:
urllib.urlretrieve('http://google.com/abc.jpg', 'abc.jpg')
nur leise zurückkehrt, auch wenn abc.jpg nicht auf google.com Server nicht vorhanden ist, ist die erzeugte abc.jpg
keine gültige jpg-Datei, es ist eigentlich eine HTML-Seite. Ich denke, den zurückgegebenen Header (a httplib.HTTPMessage Instanz) verwendet werden kann, tatsächlich, ob der Abruf Erfolge zu sagen oder nicht, aber ich kann keine doc für httplib.HTTPMessage
finden.
Kann jemand einige Informationen zu diesem Problem?
Lösung
Betrachten urllib2
wenn es möglich, in Ihrem Fall verwenden. Es ist weiter fortgeschritten und leicht zu bedienen als urllib
.
Sie können alle HTTP-Fehler leicht erkennen:
>>> 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
ist eigentlich HTTPResponse
Objekt, das Sie viele nützliche Dinge mit tun können:
>>> resp = urllib2.urlopen("http://google.com/")
>>> resp.code
200
>>> resp.headers["content-type"]
'text/html; charset=windows-1251'
>>> resp.read()
"<<ACTUAL HTML>>"
Andere Tipps
Ich halte es einfach:
# 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
Nach der Dokumentation wird undokumentierte
, um Zugriff auf die Nachricht zu bekommen es, wie Sie etwas tun, wie folgt aussieht:
a, b=urllib.urlretrieve('http://google.com/abc.jpg', r'c:\abc.jpg')
b ist die Nachrichteninstanz
Da habe ich gelernt, dass Python es immer nützlich ist Pythons der Fähigkeit zu verwenden gekehrt zu sein, wenn ich schreibe
dir(b)
Ich sehe viele Methoden oder Funktionen spielen
Und ich begann dann Dinge zu tun, mit b
zum Beispiel
b.items()
Listen viele interessante Dinge, ich vermute, dass mit diesen Dingen um spielen können Sie das Attribut, das Sie bearbeiten möchten, erhalten.
Es ist dies die Antwort eines solchen Anfänger, aber ich versuche zu meistern, wie die Selbstbeobachtung Fähigkeiten nutzen, um mein Lernen und Ihre Fragen zu verbessern gerade nach oben geknallt.
Nun, ich etwas Interessantes im Zusammenhang mit versucht, dies-ich mich gefragt, ob ich automatisch die Ausgabe von jedem der Dinge bekommen konnte, die im Verzeichnis auftauchten, die keine Parameter brauchten so schrieb ich:
needparam=[]
for each in dir(b):
x='b.'+each+'()'
try:
eval(x)
print x
except:
needparam.append(x)
Sie können einen neuen URLopener erstellen (erben von FancyURLopener) und Ausnahmen werfen oder Fehler irgendeine Art und Weise behandeln Sie wollen. Leider ignoriert FancyURLopener 404 und andere Fehler. Sehen Sie diese Frage:
beendete ich mit meiner eigenen retrieve
Implementierung mit Hilfe von pycurl
bis es mehr Protokolle als urllib / urllib2 unterstützt, hoffen, kann es anderen Menschen helfen.
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
:) Mein erster Beitrag auf Stackoverflow, haben ein Lurker seit Jahren. :)
Leider dir (urllib.urlretrieve) ist mangelhaft in nützliche Informationen. So aus diesem Thread bisher habe ich versucht, dies zu schreiben:
a,b = urllib.urlretrieve(imgURL, saveTo)
print "A:", a
print "B:", b
, die erzeugt dies:
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
Ich denke, man kann prüfen:
if b.Content-Length > 0:
Mein nächster Schritt ist es, ein Szenario zu testen, wo das Abrufen nicht ...
Ergebnisse gegen einen anderen Server / Website - was in „B“ zurückkommt, ist ein bisschen zufällig, aber man kann für bestimmte Werte testen:
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
In dem 'schlechten' Fall (nicht vorhandene Bilddatei) "B" abgerufen ein kleines Stück (Googlebot?) HTML-Code und speicherte es als Ziel, damit Content-Length von 1363 Bytes.