我有一個 Pandas 資料框,其中有一列是每個電子郵件地址的主機名(超過 1000 行):
email hostname
[email protected] example.com
[email protected] example.com
[email protected] example2.com
[email protected] example3.com
我想檢查每個主機名并檢查它是否真的存在。
email hostname valid_hostname
[email protected] example.com True
[email protected] example.com False
[email protected] example2.com False
[email protected] example3.com False
首先,我提取了每個電子郵件地址的主機名:
df['hostname'] = df['email'].str.split('@').str[1]
于是,我嘗試使用檢查DNS pyIsEmail,但這是太緩慢:
from pyisemail import is_email
df['valid_hostname'] = df['hostname'].apply(lambda x: is_email(x, check_dns=True))
然后,我嘗試了一個多執行緒函式:
import requests
from requests.exceptions import ConnectionError
def validate_hostname_existence(hostname:str):
try:
response = requests.get(f'http://{hostname}', timeout=0.5)
except ConnectionError:
return False
else:
return True
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor() as executor:
df['valid_hostname'] = pd.Series(executor.map(validate_hostname_existence, df['hostname']),index=df['hostname'].index)
但這也不太順利,因為我對并行函式還很陌生。它有多個錯誤,我相信如果我能以某種方式首先檢查這個主機名是否已經被檢查并再次跳過整個請求,它會更有益。我想在不實際發送電子郵件的情況下盡可能地進行。
有沒有圖書館或方法來實作這一點?因為到目前為止我找不到解決這個問題的正確方法。
uj5u.com熱心網友回復:
您回答自己,您可以使用快取將您已經檢查過的主機名保存在記憶體中。
例如:
from functools import lru_cache
@lru_cache(max_size=None)
def my_is_email(x, check_dns=True):
return is_email(x, check_dns=check_dns)
還建議限制大小以防止記憶體溢位。例如:
@lru_cache(max_size=256)
欲了解更多資訊,請閱讀此
uj5u.com熱心網友回復:
我對熊貓一無所知,但這里是您如何并行處理電子郵件串列并取回一組有效電子郵件的方法。我相信您可以根據自己的熊貓情況進行調整。
from queue import Empty, Queue
from threading import Thread, Lock
from pyisemail import is_email
q = Queue()
lock = Lock()
valid = set()
emails = ["[email protected]", "[email protected]"]
for e in emails:
q.put(e)
def process_queue(queue: Queue):
while True:
try:
email = queue.get(block=False)
except Empty:
break
if is_email(email, check_dns=True):
lock.acquire()
valid.add(email)
lock.release()
NUM_THREADS = 30
threads = []
for i in range(NUM_THREADS):
thread = Thread(target=process_queue, args=(q,))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
print("done")
print(valid)
解釋
- 創建一個填充電子郵件的佇列物件
- 創建 NUM_THREADS 個執行緒。
- 每個執行緒從佇列中拉取。如果他們收到電子郵件,它會處理電子郵件。鎖定保護結果集的鎖。添加到集合中。發布。如果沒有留下電子郵件,則執行緒終止。
- 等待所有執行緒終止。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/366715.html
上一篇:使用執行緒從網站上查找鏈接
