簡體   English   中英

使用python3提取字符串中的所有網址

[英]Extract all urls in a string with python3

我試圖找到一種干凈的方法來提取文本字符串中的所有 url。

經過廣泛的搜索,我發現許多帖子建議使用正則表達式來完成任務,並且他們給出了假設這樣做的正則表達式。 每個 RegEx 都有一些優點和一些缺點。 此外,編輯它們以改變它們的行為也不是一蹴而就的。 無論如何,在這一點上,我對任何可以正確檢測此文本中的 url 的 RegEx 感到滿意:

輸入:

Lorem ipsum dolor 坐 amet https://www.lorem.com/ipsum.php?q=suas , nusquam tincidunt ex per, ius modus integre no, quando utroque placerat qui no. Mea 結論emque vituperatoribus et, omnes malorum est id, pri omnes atomorum expetenda ex。 Elit pertinacia no eos, nonumy comprehensam id mei。 Ei eum maiestatis quaerendum https://www.lorem.org 😀。 Pri posse constituam in,坐http://news.bbc.co.uk omn​​ium assentior definitionem ei。 Cu duo equidem meliore qualisque。

輸出:

[ ' https://www.lorem.com/ipsum.php?q=suas ', ' https://www.lorem.org ', ' http://news.bbc.co.uk ']

但是如果有一個 python3 類/函數/庫,它會在給定的文本中找到所有 url 並接受參數:

  1. 選擇要檢測的協議
  2. 選擇允許使用哪些 TLD
  3. 選擇允許哪些域

我會很高興知道這件事。

除了其他人提到的內容之外,由於您要求已經存在的內容,您可能想嘗試URLExtract

顯然,它試圖在給定的文本中找到任何出現的TLD 如果找到 TLD,它會從該位置開始將邊界擴展到搜索“停止字符”(通常是空格、逗號、單引號或雙引號)的雙方。

這里有幾個例子。

from urlextract import URLExtract

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

似乎這個模塊還有一個update()方法可以讓你更新TLD列表緩存文件

但是,如果這不符合您的特定要求,您可以在使用上述模塊(或任何其他解析 URL 的方式)處理 url 后手動進行一些檢查。 例如,假設您獲得了一個 URL 列表:

result = ['https://www.lorem.com/ipsum.php?q=suas', 'https://www.lorem.org', 'http://news.bbc.co.uk'] 

然后,您可以構建另一個包含排除域 / TLD / 等的列表:

allowed_protocols = ['protocol_1', 'protocol_2']
allowed_tlds = ['tld_1', 'tld_2', 'tld_3']
allowed_domains = ['domain_1']

for each_url in results:
    # here, check each url against your rules

如果你想要一個正則表達式,你可以使用這個:

import re


string = "Lorem ipsum dolor sit amet https://www.lorem.com/ipsum.php?q=suas, nusquam tincidunt ex per, ius modus integre no, quando utroque placerat qui no. Mea conclusionemque vituperatoribus et, omnes malorum est id, pri omnes atomorum expetenda ex. Elit pertinacia no eos, nonumy comprehensam id mei. Ei eum maiestatis quaerendum https://www.lorem.org😀. Pri posse constituam in, sit http://news.bbc.co.uk omnium assentior definitionem ei. Cu duo equidem meliore qualisque."

result = re.findall(r"\w+://\w+\.\w+\.\w+/?[\w\.\?=#]*", string)
print(result)

輸出:

['https://www.lorem.com/ipsum.php?q=suas', 
 'https://www.lorem.org', 
 'http://news.bbc.co.uk']
import re
import string
text = """
Lorem ipsum dolor sit amet https://www.lore-m.com/ipsum.php?q=suas, 
nusquam tincidunt ex per, ftp://link.com ius modus integre no, quando utroque placerat qui no. 
Mea conclusionemque vituperatoribus et, omnes malorum est id, pri omnes atomorum expetenda ex. 
Elit ftp://link.work.in pertinacia no eos, nonumy comprehensam id mei. Ei eum maiestatis quaerendum https://www.lorem.org😀. 
Pri posse constituam in, sit http://news.bbc.co.uk omnium assentior definitionem ei. Cu duo equidem meliore 
qualisque.
"""

URL_REGEX = r"""((?:(?:https|ftp|http)?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|org|uk)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|uk|ac)\b/?(?!@)))"""

urls = re.findall(URL_REGEX, text)
print([''.join(x for x in url if x in string.printable) for url in urls])

現在,如果您只想保留具有有效域的 url,您可以將其編寫如下:

VALID_DOMAINS = ['lorem.org', 'bbc.co.uk', 'sample.com', 'link.net']
valid_urls = []
for url in result_url:
    for val_domain in VALID_DOMAINS:
        if val_domain in url:
            valid_urls.append(url)
print(valid_urls)
output = [x for x in input().split() if x.startswith('http://') or x.startswith('https://') or x.startswith('ftp://')]
print(output)

你的例子: http : //ideone.com/wys57x

畢竟,如果不是字母,您還可以剪切列表元素中的最后一個字符。

編輯:

output = [x for x in input().split() if x.startswith('http://') or x.startswith('https://') or x.startswith('ftp://')]
newOutput = []
for link in output:
    copy = link
    while not copy[-1].isalpha():
        copy = copy[:-1]
    newOutput.append(copy)
print(newOutput)

你的例子: http : //ideone.com/gHRQ8w

使用現有的庫可能是最好的解決方案。

但這對我的小腳本來說太過分了,而且——受到@piotr-wasilewiczs 回答的啟發——我想出了:

from string import ascii_letters
links = [x for x in line.split() if x.strip(str(set(x) - set(ascii_letters))).startswith(('http', 'https', 'www'))]
  • 對於行中的每個單詞,
  • 去除(從頭到尾)在單詞本身中找到的非 ASCII 字母)
  • 並按以 https、http、www 之一開頭的單詞進行過濾。

對我的口味來說有點太密集了,我不知道它有多快,但它應該可以檢測到字符串中大多數“正常”的 url。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM