2010-11-17 14 views
12

Quiero ser capaz de tomar una URL acortada o no abreviada y devolver su forma abreviada. ¿Cómo puedo hacer un programa de Python para hacer esto?¿Cómo puedo eliminar una URL?

Aclaración adicional:

  • Caso 1: acortado -> unshortened
  • Caso 2: unshortened -> unshortened

por ejemplo bit.ly/silly en la matriz de entrada debe ser google.com en la matriz de salida
p. google.com en la matriz de entrada debe ser google.com en la matriz de salida

+2

¿Está hablando de un servicio de acortamiento de URL específico, y este servicio tiene una API de la que puede recuperar la información? – JAL

Respuesta

31

enviar una solicitud HTTP HEAD a la URL y mirar el código de respuesta. Si el código es 30x, mira el encabezado Location para obtener la URL no acortada. De lo contrario, si el código es 20x, entonces la URL no se redirecciona; probablemente también desee manejar los códigos de error (4xx y 5xx) de alguna manera. Por ejemplo:

# This is for Py2k. For Py3k, use http.client and urllib.parse instead, and 
# use // instead of/for the division 
import httplib 
import urlparse 

def unshorten_url(url): 
    parsed = urlparse.urlparse(url) 
    h = httplib.HTTPConnection(parsed.netloc) 
    h.request('HEAD', parsed.path) 
    response = h.getresponse() 
    if response.status/100 == 3 and response.getheader('Location'): 
     return response.getheader('Location') 
    else: 
     return url 
+0

ignora la consulta url, una mejor versión aquí: http://stackoverflow.com/a/7153185/818634 – DmitrySandalov

+3

tenga en cuenta cuando se utiliza el código anterior no lo hace desmarque recursivamente en caso de que quiera obtener la URL real. Pruebe con 'http: // t.co/hAplNMmSTg'. Debes hacer 'return unshorten_url (response.getheader ('Location'))' para recursividad. –

+1

Posiblemente también realice un seguimiento de las URL anteriores en un conjunto para evitar la recursión cíclica. – Herbert

5

Unshorten.me tiene una API que le permite enviar una solicitud JSON o XML y obtener la URL completa devuelta.

3

abrir la URL y ver lo que resuelve:

>>> import urllib2 
>>> a = urllib2.urlopen('http://bit.ly/cXEInp') 
>>> print a.url 
http://www.flickr.com/photos/[email protected]/346615997/sizes/l/ 
>>> a = urllib2.urlopen('http://google.com') 
>>> print a.url 
http://www.google.com/ 
+3

Esto hace un GET de toda la página. Si la página no es una redirección y resulta ser muy grande, está desperdiciando una gran cantidad de ancho de banda solo para determinar que no se trata de una redirección. Es mucho mejor usar una solicitud HEAD en su lugar. –

+1

@ Adam Rosenfeld: Probablemente sea una respuesta adecuada para un proyecto paralelo para alguien que comienza Python. No recomiendo que las páginas de araña de Google o Yahoo como esta encuentren la URL real. – hughdbrown

+0

Es una ** NO BUENA IDEA ** haciendo esto.Pierdes mucho ancho de banda. Simplemente usando http://unshort.me api es mejor y más rápido que @ user387049 sugirió – Cory

13

El uso de solicitudes:

import requests 

session = requests.Session() # so connections are recycled 
resp = session.head(url, allow_redirects=True) 
print(resp.url) 
+1

Me gusta esta solución, sigue automáticamente varias redirecciones – neuhaus

+0

Simple y funciona. Me encanta – madtyn

1

Aquí un código src que tiene en cuenta casi de los casos de esquina útiles:

  • conjunto un tiempo de espera personalizado.
  • configura un agente de usuario personalizado.
  • compruebe si tenemos que usar una conexión http o https.
  • resuelven recursivamente la url de entrada y evitan que finalice dentro de un bucle.

El código src está en GitHub @https://github.com/amirkrifa/UnShortenUrl

comentarios son bienvenidos ...

import logging 
logging.basicConfig(level=logging.DEBUG) 

TIMEOUT = 10 
class UnShortenUrl: 
    def process(self, url, previous_url=None): 
     logging.info('Init url: %s'%url) 
     import urlparse 
     import httplib 
     try: 
      parsed = urlparse.urlparse(url) 
      if parsed.scheme == 'https': 
       h = httplib.HTTPSConnection(parsed.netloc, timeout=TIMEOUT) 
      else: 
       h = httplib.HTTPConnection(parsed.netloc, timeout=TIMEOUT) 
      resource = parsed.path 
      if parsed.query != "": 
       resource += "?" + parsed.query 
      try: 
       h.request('HEAD', 
          resource, 
          headers={'User-Agent': 'curl/7.38.0'} 
            } 
         ) 
       response = h.getresponse() 
      except: 
       import traceback 
       traceback.print_exec() 
       return url 

      logging.info('Response status: %d'%response.status) 
      if response.status/100 == 3 and response.getheader('Location'): 
       red_url = response.getheader('Location') 
       logging.info('Red, previous: %s, %s'%(red_url, previous_url)) 
       if red_url == previous_url: 
        return red_url 
       return self.process(red_url, previous_url=url) 
      else: 
       return url 
     except: 
      import traceback 
      traceback.print_exc() 
      return None 
+2

Aunque este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace para referencia. Las respuestas solo de enlace pueden dejar de ser válidas si la página vinculada cambia – Joel

+0

thx, se hace :) –

+0

Si entiendo su flujo correctamente, es posible que desee para ponerle un límite a la cantidad de redireccionamientos que toleraremos – Foon

0

Para unshort, puede utilizar peticiones. Esta es una solución simple que funciona para mí.

import requests 
url = "http://foo.com" 

site = requests.get(url) 
print(site.url) 
Cuestiones relacionadas