2012-03-18 24 views
8

Por ejemplo:¿Cómo extraes una URL de una cadena usando Python?

string = "This is a link http://www.google.com" 

¿Cómo podría extraer 'http://www.google.com'?

(Cada enlace será del mismo formato, es decir 'http: //')

+0

Puede que le eches un vistazo a esta respuesta: http://stackoverflow.com/questions/499345/regular-expression-to-extract-url-from-an-html-link – rjz

+0

No se devuelve ninguna cuando intento esa solución. – Sheldon

+1

Si esto es para un archivo de texto sin formato (como se expresa en su pregunta), puede verificar esta respuesta: http: // stackoverflow.com/questions/839994/extracting-a-url-in-python –

Respuesta

20

Puede haber algunas maneras de hacer esto, pero la más limpia sería utilizar expresiones regulares

>>> myString = "This is a link http://www.google.com" 
>>> print re.search("(?P<url>https?://[^\s]+)", myString).group("url") 
http://www.google.com 

Si hay puede haber múltiples enlaces se pueden utilizar algo parecido a continuación

>>> myString = "These are the links http://www.google.com and http://stackoverflow.com/questions/839994/extracting-a-url-in-python" 
>>> print re.findall(r'(https?://[^\s]+)', myString) 
['http://www.google.com', 'http://stackoverflow.com/questions/839994/extracting-a-url-in-python'] 
>>> 
+5

Esto es demasiado crudo para muchos escenarios del mundo real. Falla por completo para 'ftp: //' URLs y 'mailto:' URLs, etc., y capturará ingenuamente la parte de cola de 'Click here' (es decir, a través de "hacer clic"). – tripleee

+0

@tripleee La pregunta no es sobre analizar HTML, sino encontrar una URL en una cadena de texto que siempre tendrá el formato 'http'. Entonces esto funciona muy bien para eso. Pero sí, es muy importante que la gente sepa lo que dices si están aquí para analizar HTML o similar. – teewuane

7

con el fin de encontrar una dirección web en una cadena genérica, se puede utilizar un regular expression (regex).

Una simple expresión regular para la coincidencia de URL como la siguiente debe ajustarse a su caso.

regex = r'(' 

    # Scheme (HTTP, HTTPS, FTP and SFTP): 
    regex += r'(?:(https?|s?ftp):\/\/)?' 

    # www: 
    regex += r'(?:www\.)?' 

    regex += r'(' 

    # Host and domain (including ccSLD): 
    regex += r'(?:(?:[A-Z0-9][A-Z0-9-]{0,61}[A-Z0-9]\.)+)' 

    # TLD: 
    regex += r'([A-Z]{2,6})' 

    # IP Address: 
    regex += r'|(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' 

    regex += r')' 

    # Port: 
    regex += r'(?::(\d{1,5}))?' 

    # Query path: 
    regex += r'(?:(\/\S+)*)' 

    regex += r')' 

Si quieres ser aún más preciso, en la sección de TLD, debe asegurarse de que el dominio de nivel superior es un dominio de nivel superior válido (ver la lista completa de dominios de primer nivel válidos aquí: https://data.iana.org/TLD/tlds-alpha-by-domain.txt):

# TLD: 
    regex += r'(com|net|org|eu|...)' 

a continuación, sólo tiene que compilar la expresión regular anterior y usarlo para encontrar posibles coincidencias:

import re 

    string = "This is a link http://www.google.com" 

    find_urls_in_string = re.compile(regex, re.IGNORECASE) 
    url = find_urls_in_string.search(string) 

    if url is not None and url.group(0) is not None: 
     print("URL parts: " + str(url.groups())) 
     print("URL" + url.group(0).strip()) 

lo cual, en el caso de la cadena "Este es un enlace http://www.google.com "la salida voluntad:

URL parts: ('http://www.google.com', 'http', 'google.com', 'com', None, None) 
    URL: http://www.google.com 

Si cambia la entrada con una URL más compleja, por ejemplo 'Esta es también una URL https://www.host.domain.com:80/path/page.php?query=value&a2=v2#foo pero esto no es más' la salida será:

URL parts: ('https://www.host.domain.com:80/path/page.php?query=value&a2=v2#foo', 'https', 'host.domain.com', 'com', '80', '/path/page.php?query=value&a2=v2#foo') 
    URL: https://www.host.domain.com:80/path/page.php?query=value&a2=v2#foo 

NOTA: Si busca más URL en una sola cadena, igual puede usar la misma expresión regular, pero solo use findall() en lugar de search().

+1

Entonces, la expresión regular termina siendo '((? :(https? | S? Ftp): \/\ /)? (?: www \.)? ((?: (?: [A-Z0-9] [A-Z0-9 -] {0,61} [A-Z0-9] \.) +) ([AZ] {2,6}) | (?: \ D {1,3} \. \ D {1,3} \. \ D {1,3} \. \ D {1,3})) (? :: (\ d {1,5}))? (?: (\/\ S +) *)) '. También tenga en cuenta que la [lista de TLD] (https://data.iana.org/TLD/tlds-alpha-by-domain.txt) en este momento también incluye terminaciones divertidas como 'XN - VERMGENSBERATUNG-PWB', que tienen 24 caracteres de largo , que no será atrapado por esto. – luckydonald

+0

Sería mejor agregar '(? I)' al patrón - más portátil. Además, tenga en cuenta que esto coincidirá con '23.084.828.566', que no es una dirección IP válida, pero es un valor flotante válido en algunas configuraciones regionales. –

5

Hay otra manera de extraer URLs del texto fácilmente. Puede utilizar urlextract que lo haga por usted, sólo lo instale a través de pepita:

pip install urlextract 

y luego se puede utilizar de esta manera:

from urlextract import URLExtract 

extractor = URLExtract() 
urls = extractor.find_urls("Let's have URL stackoverflow.com as an example.") 
print(urls) # prints: ['stackoverflow.com'] 

Puede encontrar más información en mi página de GitHub: https://github.com/lipoja/URLExtract

NOTA: descarga una lista de TLD de iana.org para mantenerlo actualizado. Pero si el programa no tiene acceso a Internet, entonces no es para ti.

Cuestiones relacionadas