2012-03-18 22 views
8

Per esempio:Come si estrae un url da una stringa usando python?

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

Come potrei estrarre 'http://www.google.com'?

(Ogni link sarà dello stesso formato cioe 'http: //')

+0

Puoi dare un'occhiata a questa risposta: http://stackoverflow.com/questions/499345/regolare-espressione-per-estratto-url-from-an-html-link – rjz

+0

Nessuno viene restituito quando provo quella soluzione. – Sheldon

+1

Se si tratta di un file di testo non elaborato (come espresso nella domanda), è possibile controllare questa risposta: http: // stackoverflow.it/questions/839994/extracting-a-url-in-python –

risposta

20

Ci possono essere alcuni modi per farlo, ma il più pulito potrebbe essere quella di utilizzare regex

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

Se c'è può essere più link che è possibile utilizzare qualcosa di simile al di sotto

>>> 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

Questo è troppo grezzo per molti scenari del mondo reale. Non riesce completamente per gli URL 'ftp: //' e 'mailto:' URL, ecc e ingenuamente prenderà la parte di coda da 'Click here' (cioè attraverso "clic"). – tripleee

+0

@ triple La domanda non riguarda l'analisi dell'HTML, ma la ricerca di un URL in una stringa di testo che sarà sempre in formato "http". Quindi funziona molto bene per questo. Ma sì, è abbastanza importante per le persone sapere cosa stai dicendo se sono qui per analizzare HTML o simili. – teewuane

7

al fine di trovare un URL web in una stringa generica, è possibile utilizzare un regular expression (regex).

Una semplice espressione regolare per la corrispondenza dell'URL come la seguente dovrebbe corrispondere al 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')' 

Se si vuole essere ancora più precisi, nella sezione di dominio di primo livello, è necessario assicurarsi che il dominio di primo livello è un dominio di primo livello valido (vedere l'intero elenco di domini di primo livello validi qui: https://data.iana.org/TLD/tlds-alpha-by-domain.txt):

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

Poi, si può semplicemente compilare il precedente regex e utilizzarlo per trovare possibili incontri:

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()) 

il che, nel caso della stringa "Questo è un link http://www.google.com "output volontà:

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

Se si modifica l'ingresso con un URL più complessi, per esempio 'Questo è anche un URL https://www.host.domain.com:80/path/page.php?query=value&a2=v2#foo ma questa non è più' l'uscita sarà:

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: Se si cercano più URL in una singola stringa, è comunque possibile utilizzare la stessa espressione regolare, ma è sufficiente utilizzare findall() anziché search().

+1

Quindi, la regex risulta essere '((: :(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 +) *)) '. Nota anche che [la lista TLD] (https://data.iana.org/TLD/tlds-alpha-by-domain.txt) include anche terminazioni divertenti come 'XN - VERMGENSBERATUNG-PWB', lunghe 24 caratteri , che non sarà catturato da questo. – luckydonald

+0

Sarebbe meglio aggiungere '(? I)' al modello - più portabile. Inoltre, tieni presente che questo corrisponderà a '23.084.828.566' che non è un indirizzo IP valido ma che è un float valido in alcune impostazioni internazionali. –

5

Esiste un altro modo per estrarre facilmente gli URL dal testo. È possibile utilizzare urlextract di farlo per voi, basta installarlo tramite pip:

pip install urlextract 

e quindi è possibile utilizzare in questo modo:

from urlextract import URLExtract 

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

Potete trovare maggiori informazioni sulla mia pagina di GitHub: https://github.com/lipoja/URLExtract

NOTA: scarica un elenco di TLD da iana.org per tenerti aggiornato. Ma se il programma non ha accesso a Internet, non è per te.

Problemi correlati