JeffK Skrevet 3. juli 2008 Del Skrevet 3. juli 2008 Jeg skal lage et script som henter ned ting automatiks fra en plass på nettet. Til dette skal jeg bruke urlretrieve i modulen urllib. I listen med filer som skal lastes ned, er det en del ikke-eksisterende filer(men jeg vet ikke hvilke av dem det er). Om jeg prøver å laste ned en ikke-eksisterende fil, får jeg lastet ned en html-fil(404 melding). Er det noen måte å sjekke om en fil eksisterer(utenom å analysere innholdet). Kan man i det hele tatt skille mellom en "virkelig" fil og en 404 melding? Lenke til kommentar
terjeelde Skrevet 3. juli 2008 Del Skrevet 3. juli 2008 Jeg skal lage et script som henter ned ting automatiks fra en plass på nettet. Til dette skal jeg bruke urlretrieve i modulen urllib. I listen med filer som skal lastes ned, er det en del ikke-eksisterende filer(men jeg vet ikke hvilke av dem det er). Om jeg prøver å laste ned en ikke-eksisterende fil, får jeg lastet ned en html-fil(404 melding). Er det noen måte å sjekke om en fil eksisterer(utenom å analysere innholdet). Kan man i det hele tatt skille mellom en "virkelig" fil og en 404 melding? Spørsmålet er jo hva webserveren gir deg tilbake. Hvis den gir 200 Ok og en feilmelding, så er det ikke enkelt å se på status-kodene. Hvis den faktisk gir 404, så er det lettere å sjekke. Vanligvis pleier jo alle slike feilmeldingssider å være like, så lett nok å sjekke om du fikk en feilmelding. Selv pleier jeg ofte å bruke curl (via pycurl) til slike ting. Kan være ett godt alternativ. Lenke til kommentar
JeffK Skrevet 3. juli 2008 Forfatter Del Skrevet 3. juli 2008 Slik ser det ut om fila ikke eksisterer: http://www.start.no/tingsomikkeeksisterer Jeg kjenner ikke til HTTP-protokollen, men mistenker at det ikke gis noe feilsignal. Det kan hende webserveren bare sender en feilmeldingside. Lenke til kommentar
steingrim Skrevet 4. juli 2008 Del Skrevet 4. juli 2008 Selvfølgelig sender den ikke 200/OK på en ressurs som ikke eksisterer. Den returnerer 404/Not found akkurat slik standarden sier. Sjekk status-headeren i responsen, der vil du finne statuskoden. Lenke til kommentar
LordjOX Skrevet 16. juli 2008 Del Skrevet 16. juli 2008 Sjekk HTTP spesifikasjonen og dokumentasjonen til urllib. Ved en glance så kan du bruke URLopener sin FancyURLopener for å håndtere errors i urllib. Alternativt kan du bruke urllib2 som har enda mer error håndtering. En måte med URLopener: In [1]: import urllib, sys In [2]: try: furl = urllib.URLopener({}) o = furl.open("http://www.uio.no/noexist") o.read() except IOError, errstr: print errstr ...: ...: ('http error', 404, 'Not Found', <httplib.HTTPMessage instance at 0x847a58c>) For å lese HTTP headere eksplisitt må du nok bruke httplib. Lenke til kommentar
Cucum(r) Skrevet 20. juli 2008 Del Skrevet 20. juli 2008 (endret) Dette er vel ein grei måte å gjere det på: import httplib def is_valid_url(host, path): c = httplib.HTTPConnection(host) c.request('GET', path) response = c.getresponse() return response.status != 404 >>> is_valid_url('henriklied.no', '/sakdnkasd.html') False >>> is_valid_url('henriklied.no', '/') True Og forresten, JeffK: start.no/tingsomikkeeksiterer gir tilbake "404 Not Found" viss du inspiserer HTTP-responsen. Endret 20. juli 2008 av Henrik Lied Lenke til kommentar
JeffK Skrevet 29. juli 2008 Forfatter Del Skrevet 29. juli 2008 (endret) Takk for alle svar! Jeg endte opp med å prioritere kompakt script fremfor å optimalisere antall overførte bytes. Her er det endelige scriptet, om noen er interessert: #!/usr/bin/env python from datetime import date import hashlib import urllib import os try: import wx hasWx = True except: hasWx = False baseurl = 'http://www.start.no/tegneserier/m/mstriper/' redownload = False verbose = True duplikates = False makealbum = True strips = {} # List of md5 sums for files you already have nonex = urllib.urlopen(baseurl + "nonexistingfile").read() nonexmd5 = hashlib.md5(nonex).hexdigest() start = date(2004,10,25).toordinal() stop = date.today().toordinal() numdays = stop - start def mksubdir(direc): direcs = map(lambda s: s + '/', direc.split('/')) for i in range(0, len(direcs)): if not os.path.exists(''.join(direcs[0:(i+1)])): os.mkdir(''.join(direcs[0:(i+1)])) if hasWx: app = wx.PySimpleApp() prd = wx.ProgressDialog("Fremgang", "Fremgang", numdays, style = wx.PD_AUTO_HIDE | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME) for i in range(start, stop+1): if hasWx: prd.Update(i - start) normdate = date.fromordinal(i) if i < date(2005,1,16).toordinal(): stripfile = normdate.strftime('%d%m%Y') else: stripfile = 'm'+normdate.isoformat().replace('-','') stripfile += '.gif' if verbose: print "Laster ned stripe %i av %i(%s)... " % (i-start+1, numdays,stripfile), folder = "striper/" + str(normdate.year) + "/" + ("%02i" % normdate.month) + "/" if (not redownload) and os.path.exists(folder + stripfile): if verbose: print "eksisterer allerede" temp = open(folder + stripfile, "rb") md5sum = hashlib.md5(temp.read()).hexdigest() temp.close() if not md5sum in strips: strips[md5sum] = [(date.fromordinal(i), folder + stripfile)] elif duplikates: strips[md5sum].append((date.fromordinal(i), folder + stripfile)) continue strip = urllib.urlopen(baseurl + stripfile).read() md5sum = hashlib.md5(strip).hexdigest() if md5sum == nonexmd5: if verbose: print 'eksisterer ikke' continue if md5sum in strips: if duplikates: strips[md5sum].append((date.fromordinal(i), folder + stripfile)) else: if verbose: print 'duplikat' continue else: strips[md5sum] = [(date.fromordinal(i), folder + stripfile)] mksubdir(folder) open(folder + stripfile,"wb").write(strip) if verbose: print "ferdig" if makealbum: x = 0 s = strips.values() s.sort() album = '<html><body><center><h1>"Daglige" M-striper</h1></center>\n' for i in s: x += 1 album += str(x) + "/" + str(len(s)) + ": " + i[0][0].strftime('%d.%m.%Y') + ':<br><img src="' + i[0][1] + '"><br>\n' album += '</body></html>' f = open('album.html','w') f.write(album) f.close() Endret 29. juli 2008 av JeffK Lenke til kommentar
Cucum(r) Skrevet 29. juli 2008 Del Skrevet 29. juli 2008 (endret) JeffK: Ved å laste BODY til kvar enkelt side bruker du jo langt meir tid på å hente stripene. Her er ein liten fix: #!/usr/bin/env python from datetime import date import hashlib import urllib import httplib import os try: import wx hasWx = True except: hasWx = False def is_valid_url(host, path): c = httplib.HTTPConnection(host) c.request('GET', path) response = c.getresponse() return response.status != 404 baseurl = '/tegneserier/m/mstriper/' host = 'start.no' redownload = False verbose = True duplikates = False makealbum = True strips = {} # List of md5 sums for files you already have nonex = urllib.urlopen(baseurl + "nonexistingfile").read() nonexmd5 = hashlib.md5(nonex).hexdigest() start = date(2004,10,25).toordinal() stop = date.today().toordinal() numdays = stop - start def mksubdir(direc): direcs = map(lambda s: s + '/', direc.split('/')) for i in range(0, len(direcs)): if not os.path.exists(''.join(direcs[0:(i+1)])): os.mkdir(''.join(direcs[0:(i+1)])) if hasWx: app = wx.PySimpleApp() prd = wx.ProgressDialog("Fremgang", "Fremgang", numdays, style = wx.PD_AUTO_HIDE | wx.PD_ELAPSED_TIME | wx.PD_ESTIMATED_TIME) for i in range(start, stop+1): if hasWx: prd.Update(i - start) normdate = date.fromordinal(i) if i < date(2005,1,16).toordinal(): stripfile = normdate.strftime('%d%m%Y') else: stripfile = 'm'+normdate.isoformat().replace('-','') stripfile += '.gif' if verbose: print "Laster ned stripe %i av %i(%s)... " % (i-start+1, numdays,stripfile), folder = "striper/" + str(normdate.year) + "/" + ("%02i" % normdate.month) + "/" if (not redownload) and os.path.exists(folder + stripfile): if verbose: print "eksisterer allerede" temp = open(folder + stripfile, "rb") md5sum = hashlib.md5(temp.read()).hexdigest() temp.close() if not md5sum in strips: strips[md5sum] = [(date.fromordinal(i), folder + stripfile)] elif duplikates: strips[md5sum].append((date.fromordinal(i), folder + stripfile)) continue if is_valid_url(host, "%s%s" % (baseurl, stripfile)): strip = urllib.urlopen("%s%s%s" % (host, baseurl, stripfile)).read() md5sum = hashlib.md5(strip).hexdigest() if md5sum in strips: if duplikates: strips[md5sum].append((date.fromordinal(i), folder + stripfile)) else: if verbose: print 'duplikat' continue else: strips[md5sum] = [(date.fromordinal(i), folder + stripfile)] mksubdir(folder) open(folder + stripfile,"wb").write(strip) if verbose: print "ferdig" if makealbum: x = 0 s = strips.values() s.sort() album = '<html><body><center><h1>"Daglige" M-striper</h1></center>\n' for i in s: x += 1 album += str(x) + "/" + str(len(s)) + ": " + i[0][0].strftime('%d.%m.%Y') + ':<br><img src="' + i[0][1] + '"><br>\n' album += '</body></html>' f = open('album.html','w') f.write(album) f.close() Endret 29. juli 2008 av Henrik Lied Lenke til kommentar
JeffK Skrevet 30. juli 2008 Forfatter Del Skrevet 30. juli 2008 Ditt skript ble med min tilkobling ca 20-25% tregere. Det er sikkert fordi man må koble til to ganger for hver gyldige url(bodyen til 404-siden er jo ikke så stor). Man kunne sikkert ha tjent noe på å bare fortsette på denne eksisterende tilkoblingen. Lenke til kommentar
JeffK Skrevet 30. juli 2008 Forfatter Del Skrevet 30. juli 2008 Oppdaget at start.no gir response.status == 302 uansett om filen eksisterer eller ikke. Dette betyr at man må inn å analysere innholdet uansett. Lenke til kommentar
Zethyr Skrevet 14. august 2008 Del Skrevet 14. august 2008 302 betyr at filen er funnet, men at den egentlig er flyttet til en annen URI. Den nye URI'en sendes med i HTTP Location-feltet, anbefaler at du så prøver denne. Jeg regner med at man har HTTP Keep-alive satt, så da taper du ikke noe særlig ytelse på dette. Bruker du rette så URI'er (etter å hente dem fra 302'en) vil du få en 200 (OK) når fila finnes, og 404 (Not Found) når den er borte. Jeg er dog ikke helt sikker, ettersom du sier at man får en 302 (Found) selv om fila ikke finnes, noe som høres veldig merkelig ut. Å sjekke response.status != 404 er forøvrig en dårlig løsning, da det finnes mange andre feilkilder (403 Forbidden, 500 Internal Server Error, f.eks. for å nevne noen av de mest berømte). Du bør heller sjekke om status == 200, og evt. 302 og 307 som spesialtilfeller. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå