我有以下功能來抓取網頁。
def parse(link: str, list_of_samples: str, index: int) -> None:
# Some code to scrape the webpage (link is given)
# The code will generate a list of strings, say sample
list_of_samples[index] = sample
我有另一個腳本為串列中存在的所有 URL 呼叫上述腳本
def call_that_guy(URLs: list) -> list:
samples = [None for i in range(len(URLs))]
for i in range(len(URLs)):
parse(URLs[i], samples, i)
return samples
呼叫上述函式的其他一些函式
def caller() -> None:
URLs = [url_1, url_2, url_3, ..., url_n]
# n will not exceed 12
samples = call_thay_guy(URLs)
print(samples)
# Prints the list of samples, but is taking too much time
我注意到的一件事是決議函式需要大約 10 秒來決議單個網頁(我使用的是 Selenium)。因此,決議串列中存在的所有 URL 大約需要 2 分鐘。我想加快速度,可能使用多執行緒。
我嘗試執行以下操作。
import threading
def call_that_guy(URLs: list) -> list:
threads = [None for i in range(len(URLs))]
samples = [None for i in range(len(URLs))]
for i in range(len(URLs)):
threads[i] = threading.Thread(target = parse, args = (URLs[i], samples, i))
threads[i].start()
return samples
但是,當我列印回傳值時,它的所有內容都是 None。
我想實作什么:
我想異步抓取 URL 串列并填充示例串列。填充串列后,我還有一些其他陳述句要執行(它們應該僅在填充樣本后執行,否則它們會導致例外)。我想更快地抓取 URL 串列(允許異步),而不是一個接一個地抓取它們。

(我可以用影像更清楚地解釋一些事情)
uj5u.com熱心網友回復:
為什么不使用concurrent.futures模塊?
這是一個非常簡單但超級快速的代碼,使用concurrent.futures:
import concurrent.futures
def scrape_url(url):
print(f'Scraping {url}...')
scraped_content = '<html>scraped content!</html>'
return scraped_content
urls = ['https://www.google.com', 'https://www.facebook.com', 'https://www.youtube.com']
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
results = executor.map(scrape_url, urls)
print(list(results))
# Expected output:
# ['<html>scraped content!</html>', '<html>scraped content!</html>', '<html>scraped content!</html>']
如果你想學習執行緒,我建議你看這個簡短的教程:https : //www.youtube.com/watch?v=IEEhzQoKtQU
還要注意,這不是多處理,這是多執行緒,兩者不一樣。如果你想了解更多的區別,可以閱讀這篇文章:https : //realpython.com/python-concurrency/
希望這能解決您的問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/396526.html
上一篇:如何避免多次寫入CSV標頭
下一篇:Python檔案轉換需要2天多
