it-swarm.com.de

Wie kann ich wissen, ob urllib.urlretrieve erfolgreich ist?

urllib.urlretrieve wird im Hintergrund zurückgegeben, auch wenn die Datei auf dem Remote-HTTP-Server nicht vorhanden ist. Es speichert lediglich eine HTML-Seite in der genannten Datei. Zum Beispiel:

urllib.urlretrieve('http://google.com/abc.jpg', 'abc.jpg')

kehrt nur im Hintergrund zurück, auch wenn abc.jpg auf google.com-Servern nicht vorhanden ist, ist der generierte abc.jpg keine gültige jpg-Datei, sondern eine HTML-Seite. Ich schätze, die zurückgegebenen Header (eine httplib.HTTPMessage-Instanz) können verwendet werden, um festzustellen, ob der Abruf erfolgreich ist oder nicht. Ich kann jedoch kein Dokument für httplib.HTTPMessage finden.

Kann jemand Informationen zu diesem Problem geben?

50
btw0

Verwenden Sie urllib2, wenn dies in Ihrem Fall möglich ist. Es ist fortgeschrittener und einfacher zu bedienen als urllib.

Sie können jeden 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 ein HTTPResponse-Objekt, mit dem Sie viele nützliche Dinge ausführen können:

>>> resp = urllib2.urlopen("http://google.com/")
>>> resp.code
200
>>> resp.headers["content-type"]
'text/html; charset=windows-1251'
>>> resp.read()
"<<ACTUAL HTML>>"
25

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
6
Cees Timmerman

Laut Dokumentation ist undokumentiert

um auf die Nachricht zuzugreifen, sieht es so aus, als würden Sie etwas tun

a, b=urllib.urlretrieve('http://google.com/abc.jpg', r'c:\abc.jpg')

b ist die Nachrichteninstanz

Seit ich gelernt habe, dass Python ist, ist es immer nützlich, die Python-Fähigkeit zu nutzen, um beim Schreiben introspektiv zu sein 

dir(b) 

Ich sehe viele Methoden oder Funktionen zum Spielen

Und dann fing ich an mit b

zum Beispiel 

b.items()

Listet viele interessante Dinge auf, ich vermute, dass das Herumspielen mit diesen Dingen es Ihnen ermöglicht, das Attribut zu erhalten, das Sie manipulieren möchten.

Tut mir leid, das ist so eine Anfänger-Antwort, aber ich versuche zu beherrschen, wie ich die Introspektionsfähigkeiten einsetzen kann, um mein Lernen zu verbessern und Ihre Fragen sind aufgetaucht.

Nun, ich habe etwas Interessantes in Bezug auf dieses Thema ausprobiert - ich habe mich gefragt, ob ich automatisch die Ausgabe von allen Dingen erhalten könnte, die im Verzeichnis auftauchten und keine Parameter benötigten. Ich schrieb:

needparam=[]
for each in dir(b):
    x='b.'+each+'()'
    try:
        eval(x)
        print x
    except:
        needparam.append(x)
3
PyNEwbie

Sie können einen neuen URLopener erstellen (von FancyURLopener erben) und Ausnahmen auslösen oder Fehler auf beliebige Weise behandeln. Leider ignoriert FancyURLopener 404 und andere Fehler. Diese Frage sehen:

Wie fange ich den 404-Fehler in urllib.urlretrieve ab

2

Ich endete mit meiner eigenen retrieve-Implementierung. Mit pycurl werden mehr Protokolle unterstützt als urllib/urllib2. Ich hoffe, es kann 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
1
btw0
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
0
gzliuqingyun

Ergebnisse gegen einen anderen Server/eine andere Website - was in "B" zurückkommt, ist etwas zufällig, aber man kann nach bestimmten Werten suchen:

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

Im "schlechten" Fall (nicht vorhandene Bilddatei) hat "B" ein kleines Stück (Googlebot?) HTML-Code abgerufen und als Ziel gespeichert, daher die Inhaltslänge von 1363 Byte. 

0
fotonix

:) Mein erster Post auf StackOverflow war schon seit Jahren ein Lurker. :)

Leider ist dir (urllib.urlretrieve) nützliche Informationen unzulänglich. ___ Von diesem Thread aus habe ich bisher versucht, dies zu schreiben:

a,b = urllib.urlretrieve(imgURL, saveTo)
print "A:", a
print "B:", b

was produzierte 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 überprüfen:

if b.Content-Length > 0:

Mein nächster Schritt ist das Testen eines Szenarios, in dem das Abrufen fehlschlägt ...

0
fotonix