2009-10-28 9 views

risposta

19

Non è necessario come bobince fatto e passare a httplib. Si può fare tutto ciò che con urllib direttamente:

>>> import urllib2 
>>> f = urllib2.urlopen("http://dalkescientific.com") 
>>> f.headers.items() 
[('content-length', '7535'), ('accept-ranges', 'bytes'), ('server', 'Apache/2.2.14'), 
('last-modified', 'Sun, 09 Mar 2008 00:27:43 GMT'), ('connection', 'close'), 
('etag', '"19fa87-1d6f-447f627da7dc0"'), ('date', 'Wed, 28 Oct 2009 19:59:10 GMT'), 
('content-type', 'text/html')] 
>>> f.headers["Content-Length"] 
'7535' 
>>> 

Se si utilizza httplib allora potrebbe essere necessario implementare la gestione di reindirizzamento, supporto proxy, e le altre belle cose che urllib2 fa per voi.

1

è possibile controllare il contenuto di lunghezza in una richiesta HEAD prima, ma attenzione, questa intestazione non deve essere impostato - vedere How do you send a HEAD HTTP request in Python 2?

+0

Come faccio a controllare il contenuto di lunghezza nella richiesta HEAD? È considerato scaricare le intestazioni? – TIMEX

+0

Fare una richiesta HEAD è al meglio teorico se si desidera utilizzare urllib/urllib2. Quei moduli supportano solo richieste GET e POST. –

7

Si potrebbe dire:

maxlength= 12*1024*1024 
thefile= urllib2.urlopen(request).read(maxlength+1) 
if len(thefile)==maxlength+1: 
    raise ThrowToysOutOfPramException() 

ma ovviamente hai ancora letto 12 MB di dati indesiderati. Se vuoi minimizzare il rischio che ciò accada, puoi controllare l'intestazione HTTP Content-Length, se presente (potrebbe non esserlo). Ma per farlo devi scendere a httplib invece del più generale urllib.

u= urlparse.urlparse(ep_url) 
cn= httplib.HTTPConnection(u.netloc) 
cn.request('GET', u.path, headers= {'User-Agent': ua}) 
r= cn.getresponse() 

try: 
    l= int(r.getheader('Content-Length', '0')) 
except ValueError: 
    l= 0 
if l>maxlength: 
    raise IAmCrossException() 

thefile= r.read(maxlength+1) 
if len(thefile)==maxlength+1: 
    raise IAmStillCrossException() 

È possibile controllare la lunghezza prima di chiedere di ottenere il file, se si preferisce. Questo è fondamentalmente lo stesso di sopra, tranne che usando il metodo 'HEAD' anziché 'GET'.

+0

grazie mille. ssdf – TIMEX

+1

Questa è una soluzione migliore, poiché Content-Length non è affidabile (qualcuno potrebbe erroneamente impostarlo) –

+0

Soluzione perfetta: dovrebbe essere accettata! –

1

Ciò funzionerà se l'intestazione Content-Length è impostato

import urllib2   
req = urllib2.urlopen("http://example.com/file.zip") 
total_size = int(req.info().getheader('Content-Length')) 
+0

non è necessario '.strip()': 1. 'getheader()' restituisce già la versione 2 rimossa. 'Int()' non interessa gli spazi bianchi iniziali o finali. – jfs

+0

Inoltre, non ha senso usare 'int (info(). Getheader())' se non si imposta il valore predefinito: 'ValueError' da' int' è meno appropriato di 'KeyError' da' req.headers '(nota:' req.info() è req.headers') – jfs

+0

@Gourneau - Funzionerebbe ancora se l'url specificato fosse ftp: // url? –

Problemi correlati