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?

War es hilfreich?

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:

Wie 404-Fehler in urllib.urlretrieve fangen

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top