代码之家  ›  专栏  ›  技术社区  ›  Kyle Hayes

在python中提取URL

  •  28
  • Kyle Hayes  · 技术社区  · 17 年前

    关于: Find Hyperlinks in Text using Python (twitter related)

    如何只提取URL,以便将其放入列表/数组中?


    编辑

    让我澄清一下,我不想把URL解析成片段。我想从字符串的文本中提取URL,将其放入数组中。谢谢!

    8 回复  |  直到 7 年前
        1
  •  40
  •   Iulian Onofrei Denis Oliveira    7 年前

    为了回应OP的编辑,我劫持了 Find Hyperlinks in Text using Python (twitter related) 想到了这个:

    import re
    
    myString = "This is my tweet check it out http://example.com/blah"
    
    print(re.search("(?P<url>https?://[^\s]+)", myString).group("url"))
    
        2
  •  25
  •   SilentGhost    16 年前

    误会问题:

    >>> from urllib.parse import urlparse
    >>> urlparse('http://www.ggogle.com/test?t')
    ParseResult(scheme='http', netloc='www.ggogle.com', path='/test',
            params='', query='t', fragment='')
    

    or py2.* version :

    >>> from urlparse import urlparse
    >>> urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
    ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
    

    埃塔 :regex确实是这里的最佳选择:

    >>> s = 'This is my tweet check it out http://tinyurl.com/blah and http://blabla.com'
    >>> re.findall(r'(https?://\S+)', s)
    ['http://tinyurl.com/blah', 'http://blabla.com']
    
        3
  •  7
  •   dranxo    11 年前

    这是一个有着巨大regex的文件:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    """
    the web url matching regex used by markdown
    http://daringfireball.net/2010/07/improved_regex_for_matching_urls
    https://gist.github.com/gruber/8891611
    """
    URL_REGEX = r"""(?i)\b((?:https?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/?(?!@)))"""
    

    我叫那个文件 urlmarker.py 当我需要它的时候,我就把它进口。

    import urlmarker
    import re
    re.findall(urlmarker.URL_REGEX,'some text news.yahoo.com more text')
    

    囊性纤维变性。 http://daringfireball.net/2010/07/improved_regex_for_matching_urls 和 What's the cleanest way to extract URLs from a string using Python?

        4
  •  3
  •   SilentGhost    16 年前

    关于这一点:

    import re
    myString = "This is my tweet check it out http:// tinyurl.com/blah"
    print re.search("(?P<url>https?://[^\s]+)", myString).group("url")
    

    如果字符串中有多个URL,它将无法正常工作。 如果字符串看起来像:

    myString = "This is my tweet check it out http:// tinyurl.com/blah and http:// blabla.com"
    

    你可以这样做:

    myString_list = [item for item in myString.split(" ")]
    for item in myString_list:
        try:
            print re.search("(?P<url>https?://[^\s]+)", item).group("url")
        except:
            pass
    
        5
  •  3
  •   Community Mohan Dere    9 年前

    不要忘记检查搜索是否返回值 None “我发现上面的帖子很有帮助,但在处理 没有 结果。

    见 Python Regex "object has no attribute" .

    即

    import re
    myString = "This is my tweet check it out http://tinyurl.com/blah"
    match = re.search("(?P<url>https?://[^\s]+)", myString)
    if match is not None: 
        print match.group("url")
    
        6
  •  3
  •   Jan Lipovský    9 年前

    如果您想从任何文本中提取URL,可以使用我的urlextract。它根据文本中的TLD查找URL。它从TLD位置扩展到两边,得到整个URL。它很容易使用。检查一下: https://github.com/lipoja/URLExtract

        from urlextract import URLExtract
    
        extractor = URLExtract()
        urls = extractor.find_urls("Text with URLs: stackoverflow.com.")
    
        7
  •  1
  •   kyrenia    11 年前

    [注意:假设您在Twitter数据上使用这个(如问题所示),最简单的方法是使用他们的API,它将从Twitter中提取的URL作为一个字段返回]

        8
  •  1
  •   Allan    8 年前

    您可以使用以下可怕的regex:

    \b((?:https?://)?(?:(?:www\.)?(?:[\da-z\.-]+)\.(?:[a-z]{2,6})|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])))(?::[0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?(?:/[\w\.-]*)*/?)\b
    

    Demo regex101

    此regex将接受以下格式的URL:

    输入:

    add1 http://mit.edu.com abc
    add2 https://facebook.jp.com.2. abc
    add3 www.google.be. uvw
    add4 https://www.google.be. 123
    add5 www.website.gov.us test2
    Hey bob on www.test.com. 
    another test with ipv4 http://192.168.1.1/test.jpg. toto2
    website with different port number www.test.com:8080/test.jpg not port 80
    www.website.gov.us/login.html
    test with ipv4 192.168.1.1/test.jpg.
    search at google.co.jp/maps.
    test with ipv6 2001:0db8:0000:85a3:0000:0000:ac1f:8001/test.jpg.
    

    输出:

    http://mit.edu.com
    https://facebook.jp.com
    www.google.be
    https://www.google.be
    www.website.gov.us
    www.test.com
    http://192.168.1.1/test.jpg
    www.test.com:8080/test.jpg
    www.website.gov.us/login.html
    192.168.1.1/test.jpg
    google.co.jp/maps
    2001:0db8:0000:85a3:0000:0000:ac1f:8001/test.jpg
    

    说明:

    • \b 用于单词边界分隔URL和其余文本
    • (?:https?://)? 匹配http://或https/(如果存在)
    • (?:(?:www\.)?(?:[\da-z\.-]+)\.(?:[a-z]{2,6}) 匹配标准URL(可能以 www. (我们称之为 STANDARD_URL )
    • (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) 为了匹配标准的IPv4(我们称之为 IPv4 )
    • 要匹配IPv6 URL,请执行以下操作: (?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])) (我们称之为 IPv6 )
    • 匹配端口部分(我们称之为 PORT 如果存在: (?::[0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])
    • 匹配 (?:/[\w\.-]*)*/?) URL的目标对象部分(HTML文件,JPG,…)(让我们调用它 RESSOURCE_PATH )

    这给了 遵从正则表达式 :

    \b((?:https?://)?(?:STANDARD_URL|IPv4|IPv6)(?:PORT)?(?:RESSOURCE_PATH)\b
    

    资料来源:

    IPv6 : Regular expression that matches valid IPv6 addresses

    IPv4 : https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html

    端口 : https://stackoverflow.com/a/12968117/8794221

    其他来源: https://code.tutsplus.com/tutorials/8-regular-expressions-you-should-know--net-6149


    $ more url.py
    
    import re
    
    inputString = """add1 http://mit.edu.com abc
    add2 https://facebook.jp.com.2. abc
    add3 www.google.be. uvw
    add4 https://www.google.be. 123
    add5 www.website.gov.us test2
    Hey bob on www.test.com. 
    another test with ipv4 http://192.168.1.1/test.jpg. toto2
    website with different port number www.test.com:8080/test.jpg not port 80
    www.website.gov.us/login.html
    test with ipv4 (192.168.1.1/test.jpg).
    search at google.co.jp/maps.
    test with ipv6 2001:0db8:0000:85a3:0000:0000:ac1f:8001/test.jpg."""
    
    regex=ur"\b((?:https?://)?(?:(?:www\.)?(?:[\da-z\.-]+)\.(?:[a-z]{2,6})|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])))(?::[0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?(?:/[\w\.-]*)*/?)\b"
    
    matches = re.findall(regex, inputString)
    print(matches)
    

    输出:

    $ python url.py 
    ['http://mit.edu.com', 'https://facebook.jp.com', 'www.google.be', 'https://www.google.be', 'www.website.gov.us', 'www.test.com', 'http://192.168.1.1/test.jpg', 'www.test.com:8080/test.jpg', 'www.website.gov.us/login.html', '192.168.1.1/test.jpg', 'google.co.jp/maps', '2001:0db8:0000:85a3:0000:0000:ac1f:8001/test.jpg']