2012-03-18 33 views
8

Na przykład:Jak wyodrębnić URL z łańcucha za pomocą python?

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

Jak mogłem wydobyć 'http://www.google.com'?

(Każde ogniwo będzie tym samym formacie Ie 'http: //')

+0

Możesz sprawdzić tę odpowiedź: http://stackoverflow.com/questions/499345/regular-expression-to-extract-url-from-an-html-link – rjz

+0

Żaden nie jest zwracany, gdy próbuję tego rozwiązania. – Sheldon

+1

Jeśli dotyczy to nieprzetworzonego pliku tekstowego (jak podano w pytaniu), możesz sprawdzić tę odpowiedź: http: // stackoverflow.com/questions/839994/extracting-a-url-in-python –

Odpowiedz

20

Może istnieć kilka sposobów, aby to zrobić, ale to najczystszy byłoby użyć regex

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

jeśli istnieje może być wiele linków można użyć coś podobnego do poniżej

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

To jest zbyt prymitywne dla wielu rzeczywistych scenariuszy. Zupełnie nie działa z 'ftp: //' adresami URL i 'mailto:' adresami URL itp., I naiwnie pobierze część końcową z 'Click here' (tj. Do "kliknięcia"). – tripleee

+0

@tripleee Pytanie nie dotyczy parsowania HTML, ale szukania adresu URL w ciągu tekstowym, który zawsze będzie miał format "http". Tak więc działa to bardzo dobrze. Ale tak, bardzo ważne dla ludzi, aby wiedzieć, co mówisz, jeśli są tutaj do parsowania HTML lub podobne. – teewuane

7

aby znaleźć adres internetowy w ogólnej ciąg, można użyć regular expression (regex).

Proste dopasowanie do dopasowania adresu URL, takie jak poniższe, powinno pasować do Twojego przypadku.

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

Jeśli chcesz być jeszcze bardziej precyzyjny, w sekcji TLD, należy upewnić się, że TLD jest poprawnym TLD (zobacz całą listę ważnych TLD tutaj: https://data.iana.org/TLD/tlds-alpha-by-domain.txt):

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

Następnie można po prostu skompilować byłego regex i użyć go do znalezienia możliwych mecze:

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

, które w przypadku napisu „to jest link http://www.google.com "Wyjście wola:

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

Jeśli zmienić wejście z bardziej złożonych URL, na przykład «Jest to również URL https://www.host.domain.com:80/path/page.php?query=value&a2=v2#foo ale to nie jest już» wyjście będzie:

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 

UWAGA: Jeśli szukasz więcej adresów URL w jednym ciągu, nadal można korzystać z tego samego wyrażenia regularnego, ale wystarczy użyć findall() zamiast search().

+1

Zatem wyrażenie regularne kończy się na '((??: 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 +) *)) '. Zauważ również, że [lista TLD] (https://data.iana.org/TLD/tlds-alpha-by-domain.txt) zawiera teraz końcówki zabawne, takie jak 'XN - VERMGENSBERATUNG-PWB', mające 24 znaki długości , który nie będzie przez to przechwytywany. – luckydonald

+0

Byłoby lepiej dodać '(? I)' do wzorca - bardziej przenośny. Pamiętaj też, że będzie to pasować do '23.084.828.566', który nie jest prawidłowym adresem IP, ale jest poprawnym zmiennym w niektórych lokalizacjach. –

5

Istnieje inny sposób łatwego wyodrębniania adresów URL z tekstu. Można użyć urlextract to zrobić dla Ciebie, wystarczy zainstalować go poprzez pip:

pip install urlextract 

i wtedy można go używać tak:

from urlextract import URLExtract 

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

można znaleźć więcej informacji na mojej stronie github: https://github.com/lipoja/URLExtract

UWAGA: To pobiera listę TLD z iana.org, aby być na bieżąco. Ale jeśli program nie ma dostępu do Internetu, to nie jest dla ciebie.

Powiązane problemy