2012-06-29 14 views
5

Mi chiedo se c'è un modo per controllare se l'url collega a un'immagine valida o no in Django.Django: controlla se esiste un'immagine in qualche particolare URL

+1

Se l'immagine è sulla stessa macchina come Django, quindi puoi semplicemente leggere il file e convalidarlo. In caso contrario, è necessario effettuare una chiamata REST e analizzare il risultato. – freakish

+0

L'immagine non esiste sulla stessa macchina di Django. Di solito ho un modulo in cui l'utente ha bisogno di inviare un URL di qualche immagine. Voglio solo verificare se quell'URL collega a qualsiasi immagine reale o meno. –

+0

Leggi questo: http://stackoverflow.com/questions/7699796/how-do-you-get-django-to-make-a-restful-call (possibile duplicato). – freakish

risposta

3

Ecco un metodo sicuro. Prima di tutto, analizza l'url per ottenere il dominio e il resto.

>>> from urllib.parse import urlparse 
>>> url = 'http://example.com/random/folder/path.html' 
>>> parse_object = urlparse(url) 
>>> parse_object.netloc 
'example.com' 
>>> parse_object.path 
'/random/folder/path.html' 
>>> parse_object.scheme 
'http' 

Ora, utilizzare le informazioni di cui sopra per ottenere il tipo di contenuto. Utilizzare lo parse_object.netloc anziché sstatic.net e lo parse_object.path anziché il percorso hardcoded.

>>> import httplib 
>>> conn = httplib.HTTPConnection("sstatic.net") 
>>> conn.request("HEAD", "/stackoverflow/img/favicon.ico") 
>>> res = conn.getresponse() 
>>> print res.getheaders() 
[('content-length', '1150'), ('x-powered-by', 'ASP.NET'), ('accept-ranges', 'bytes'),   ('last-modified', 'Mon, 02 Aug 2010 06:04:04 GMT'), ('etag', '"2187d82832cb1:0"'), ('cache-control', 'max-age=604800'), ('date', 'Sun, 12 Sep 2010 13:39:26 GMT'), ('content-type', 'image/x-icon')] 

Questo indica che è un'immagine (immagine/* tipo mime) di 1150 byte. Basta informazioni per decidere se si desidera recuperare l'intera risorsa.

EDIT

per gli URL accorciati, come http://goo.gl/IwruD che punta a http://ubuntu.icafebusiness.com/images/ubuntugui2.jpg, nella risposta che si ottiene, c'è un parametro aggiuntivo chiamato 'location'.

Ecco cosa sto parlando:

>>> import httplib 
>>> conn = httplib.HTTPConnection("goo.gl") 
>>> conn.request("HEAD", "/IwruD") 
>>> res = conn.getresponse() 
>>> print res.getheaders() 
[('x-xss-protection', '1; mode=block'), 
('x-content-type-options', 'nosniff'), 
('transfer-encoding', 'chunked'), 
('age', '64'), 
('expires', 'Mon, 01 Jan 1990 00:00:00 GMT'), 
('server', 'GSE'), 
('location', 'http://ubuntu.icafebusiness.com/images/ubuntugui2.jpg'), 
('pragma', 'no-cache'), 
('cache-control', 'no-cache, no-store, max-age=0, must-revalidate'), 
('date', 'Sat, 30 Jun 2012 08:52:15 GMT'), 
('x-frame-options', 'SAMEORIGIN'), 
('content-type', 'text/html; charset=UTF-8')] 

Mentre nella URL diretto, non si troverebbero.

>>> import httplib 
>>> conn = httplib.HTTPConnection("ubuntu.icafebusiness.com") 
>>> conn.request("HEAD", "/images/ubuntugui2.jpg") 
>>> res = conn.getresponse() 
>>> print res.getheaders() 
[('content-length', '78603'), ('accept-ranges', 'bytes'), ('server', 'Apache'), ('last-modified', 'Sat, 16 Aug 2008 01:36:17 GMT'), ('etag', '"1fb8277-1330b-45489c3ad2640"'), ('date', 'Sat, 30 Jun 2012 08:55:46 GMT'), ('content-type', 'image/jpeg')] 

È possibile cercare che l'utilizzo di un semplice codice:

>>> r = res.getheaders() 
>>> redirected = False 
>>> for e in r: 
>>>  if(e[0] == 'location'): 
>>>   redirected = e 
>>> 
>>> if(redirected != False): 
>>>  print redirected[1] 
'http://ubuntu.icafebusiness.com/images/ubuntugui2.jpg' 
+0

Il mio interprete python dice "ImportError: nessun modulo chiamato parse". Il tuo metodo non è riuscito al punto 1.Qualsiasi idea? –

+0

Trovato, stai usando python 3 mentre sto ancora usando python 2.7 :) –

+0

Un ulteriore dubbio, supponiamo che 'http://ubuntu.icafebusiness.com/images/ubuntugui2.jpg' sia l'url e l'ho accorciato usando abbreviazione URL di Google così ora diventa 'http://goo.gl/IwruD'.Ora su questo URL abbreviato il tuo metodo non funziona, si dice "ResponseNotReady". Cosa dice? –

3

Un modo semplice per verificare ciò utilizzando urllib2.

>>> import urllib2 
>>> url = 'https://www.google.com.pk/images/srpr/logo3w.png' 
>>> try: 
... f = urllib2.urlopen(urllib2.Request(url)) 
... imageFound = True 
... except: 
... imageFound = False 
... 
>>> imageFound 
True 
4

Utilizzando requests e PIL per verificare che in realtà è un'immagine valida:

>>> import requests 
>>> from PIL import Image 
>>> from StringIO import StringIO 
>>> r = requests.get('http://cdn.sstatic.net/stackoverflow/img/sprites.png') 
>>> im = Image.open(StringIO(r.content)) 
>>> im 
<PIL.PngImagePlugin.PngImageFile image mode=RGBA size=238x1073 at 0x2845EA8> 
+0

Cosa accadrebbe se l'immagine non fosse lì? il tuo codice si bloccherebbe o dovresti controllare alcuni attributi di im? Puoi aggiornare il tuo codice a una funzione che restituisce un valore booleano? – Radu

+0

'r.status_code' non sarebbe 200 – jterrace

+0

Sì a parte il codice di stato HTTP, Image.open dovrebbe lanciare qualche tipo di errore che sto pensando? PIL non è molto utile in questo ... Stavo anche guardando http://effbot.org/imagingbook/image.htm#tag-Image.Image.verify ma non riesco a capire cosa usare. – Radu

Problemi correlati