2010-03-21 31 views

Respuesta

29
>>> import httplib 
>>> 
>>> def exists(site, path): 
...  conn = httplib.HTTPConnection(site) 
...  conn.request('HEAD', path) 
...  response = conn.getresponse() 
...  conn.close() 
...  return response.status == 200 
... 
>>> exists('http://www.fakedomain.com', '/fakeImage.jpg') 
False 

Si el estado es otra cosa que un 200, el recurso no existe en la URL. Esto no significa que se haya ido del todo. Si el servidor devuelve un 301 o 302, esto significa que el recurso todavía existe, pero en una URL diferente. Para modificar la función para manejar este caso, la línea de verificación de estado solo necesita cambiarse a return response.status in (200, 301, 302).

+2

+1, aunque me imagino que usar 'HEAD' en lugar de' GET' en la llamada a 'conn.request' sería más eficiente, ya que solo está verificando si existe. –

+0

@Daniel, gracias por ese consejo. Actualicé el código para usar HEAD. – tikiboy

+0

Si ve errores similares a: ** "gaierror: [Errno 8] nodename ni servname provided, or no known" ** asegúrese de que su valor 'site' no incluya 'http: //', 'ftp: // En vez, parece que httplib intentará derivar el protocolo correcto o requiere que se especifique el número de puerto apropiado (ver comentarios adicionales a continuación). – bluebinary

0

Creo que se puede intentar enviar una solicitud HTTP a la URL y leer el response.If no es una excepción fue capturado, es probable que exista.

+0

eso es lo que intenté hacer, pero no pude encontrar ningún ejemplo de código específico. ¿Tendría uno? – user257543

+0

@ user257543 Parece que tienes una buena :) – Young

3

Parece http://www.fakedomain.com/fakeImage.jpg redirigido automáticamente a http://www.fakedomain.com/index.html sin ningún error.

El redireccionamiento de 301 y 302 respuestas se realiza automáticamente sin dar ninguna respuesta al usuario.

Por favor, eche un vistazo a HTTPRedirectHandler, puede que tenga que subclase para manejar eso.

Aquí es la que muestra de Inmersión en Python:

http://diveintopython3.ep.io/http-web-services.html#redirects

+3

Creo que fakedomain.com se usa por ejemplo como el nombre y en realidad no necesitas visitarlo tú mismo. :-) – Young

+1

@SpawnCxy, al principio pensé así , pero cuando voy a esa url, fakeImage.jpg no existe y se redirige a index.html, por lo que supongo que es más que un ejemplo. – YOU

0

No sé por qué estás haciendo esto, pero en cualquier caso: debe tenerse en cuenta que el hecho de que una solicitud a una "imagen" tenga éxito no significa que sea lo que piensas que es (podría redireccionar a cualquier cosa, o devolver datos de cualquier tipo, y potencialmente causar problemas dependiendo de lo que hagas con la respuesta).

Lo sentimos, fui en una borrachera de leer acerca de los ataques online y cómo defenderse de ellos hoy en día: P

1

Prueba con mechanize:

import mechanize 
br = mechanize.Browser() 
br.set_handle_redirect(False) 
try: 
br.open_novisit('http://www.fakedomain.com/fakeImage.jpg') 
print 'OK' 
except: 
print 'KO' 
7

gracias por todas las respuestas a todos, terminó usando lo siguiente:

try: 
    f = urllib2.urlopen(urllib2.Request(url)) 
    deadLinkFound = False 
except: 
    deadLinkFound = True 
+0

Corto n 'dulce. Lo usé yo mismo como mi cadena de URL (s) (alrededor de 5000 de ellos) fueron el URI completo --No quería ser demasiado detallado. También pude suponer que recibiría un 404 y no una redirección. No estoy seguro si esto funcionaría con una redirección. – Flowpoke

+1

Bueno, dará True en los errores URL también e incluso en 301,302,303 errores también. –

3

Hay problemas con las respuestas anteriores cuando el archivo se encuentra en el servidor FTP (ftp://url.com/file), el fol código mugido funciona cuando el archivo está en FTP, HTTP o HTTPS:

import urllib2 

def file_exists(url): 
    request = urllib2.Request(url) 
    request.get_method = lambda : 'HEAD' 
    try: 
     response = urllib2.urlopen(request) 
     return True 
    except: 
     return False 
+0

No pude obtener ninguna de las respuestas anteriores para devolver False cuando ingresé una URL de archivo incorrecta, ¡pero esta respuesta funcionó muy bien! – Darkhydro

22

El código siguiente es equivalente a tikiboy's answer, pero el uso de un alto nivel y fácil de usar requests biblioteca.

import requests 

def exists(path): 
    r = requests.head(path) 
    return r.status_code == requests.codes.ok 

print exists('http://www.fakedomain.com/fakeImage.jpg') 

El requests.codes.ok es igual a 200, por lo que puede sustituir el código de estado exacto si lo desea.

requests.head puede arrojar un exception si el servidor no responde, por lo que es posible que desee agregar una construcción try-except.

Además, si desea incluir códigos 301 y 302, considere código 303 también, especialmente si dereference URIs que denotan recursos en Linked Data. Un URI puede representar a una persona, pero no puede descargar a una persona, por lo que el servidor lo redirigirá a una página que describe a esta persona usando 303 redirect.

+0

Esta respuesta parece la forma más simple y más normal de hacer esto ahora. Consulte http://stackoverflow.com/questions/2018026/should-i-use-urllib-or-urllib2-or-requests –

+0

Funciona perfectamente en Python 3.5 frente a otras respuestas. – Eskapp

0

Esto podría ser suficiente para ver si existe una url en un archivo.

import urllib 
if urllib.urlopen('http://www.fakedomain.com/fakeImage.jpg').code == 200: 
    print 'File exists'