fix: error handling
This commit is contained in:
61
邮件批量发送脚本.py
61
邮件批量发送脚本.py
@@ -3,7 +3,7 @@ import time
|
|||||||
import csv
|
import csv
|
||||||
|
|
||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
from selenium.common.exceptions import StaleElementReferenceException, TimeoutException, ElementNotInteractableException
|
from selenium.common.exceptions import StaleElementReferenceException, TimeoutException
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.support import expected_conditions as EC
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
from selenium.webdriver.support.wait import WebDriverWait
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
@@ -18,7 +18,7 @@ parser.add_argument('--address', type=str, required=True)
|
|||||||
parser.add_argument('--password', type=str, required=True)
|
parser.add_argument('--password', type=str, required=True)
|
||||||
parser.add_argument('--encoding', type=str, nargs='?', default='utf-8')
|
parser.add_argument('--encoding', type=str, nargs='?', default='utf-8')
|
||||||
parser.add_argument('--timeout', type=int, nargs='?', default=60)
|
parser.add_argument('--timeout', type=int, nargs='?', default=60)
|
||||||
parser.add_argument('--interval', type=int, nargs='?', default=4)
|
parser.add_argument('--interval', type=int, nargs='?', default=5)
|
||||||
parser.add_argument('--rate-limit', type=int, nargs='?', default=8.33)
|
parser.add_argument('--rate-limit', type=int, nargs='?', default=8.33)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
@@ -93,13 +93,15 @@ def main():
|
|||||||
print(f'[!!!!] 读取邮件时发生了错误:{e}')
|
print(f'[!!!!] 读取邮件时发生了错误:{e}')
|
||||||
return 5
|
return 5
|
||||||
|
|
||||||
rate = 60 / (args.interval + 4)
|
rate = 60 / (args.interval + 3)
|
||||||
|
limit = len(recipients)
|
||||||
|
|
||||||
print(f'[信息] 当前发送速率 {rate} 封/分钟')
|
print(f'[信息] 当前发送速率 {round(rate, 2)} 封/分钟')
|
||||||
print(f'[信息] 预计使用时间 {timedelta(seconds=rate * len(recipients))}')
|
print(f'[信息] 预计使用时间 {timedelta(seconds=rate * limit)}')
|
||||||
|
|
||||||
if rate > args.rate_limit:
|
if rate > args.rate_limit:
|
||||||
print('[警告] 当前发送速率已超出速率限制')
|
print(f'[警告] 已设置速率限制 {round(args.rate_limit, 2)}')
|
||||||
|
print('[警告] 当前发送速率已超出限制')
|
||||||
|
|
||||||
key = input('[????] 是否确定发送?确定 (Y) / 取消 (N): ')
|
key = input('[????] 是否确定发送?确定 (Y) / 取消 (N): ')
|
||||||
|
|
||||||
@@ -110,55 +112,61 @@ def main():
|
|||||||
exit()
|
exit()
|
||||||
|
|
||||||
global date
|
global date
|
||||||
global sent
|
|
||||||
global errors
|
|
||||||
|
|
||||||
date = datetime.now()
|
date = datetime.now()
|
||||||
|
|
||||||
for recipient in recipients:
|
for recipient in recipients:
|
||||||
try:
|
try:
|
||||||
print(f'[信息] 正在发送:{recipient}')
|
print(f'[信息] 正在发送:{recipient}')
|
||||||
|
|
||||||
edit = locate(driver, EC.element_to_be_clickable, (By.CSS_SELECTOR, "button[aria-label='Edit copy']"))
|
edit = locate(driver, EC.element_to_be_clickable, (By.CSS_SELECTOR, "button[aria-label='Edit copy']"))
|
||||||
edit.click()
|
edit.click()
|
||||||
|
|
||||||
# 等待页面加载
|
draft = locate(driver, EC.element_to_be_clickable, (By.CSS_SELECTOR, "div.io-ox-mail-compose-window"))
|
||||||
locate(driver, EC.invisibility_of_element_located, (By.CSS_SELECTOR, "div.window-blocker.io-ox-busy"))
|
|
||||||
|
|
||||||
mails = driver.find_elements(By.CSS_SELECTOR, "div.io-ox-mail-compose-window")
|
|
||||||
draft = mails[-1:][0]
|
|
||||||
|
|
||||||
# 等待页面加载
|
|
||||||
locate(driver, EC.invisibility_of_element_located, (By.CSS_SELECTOR, "div.window-blocker.io-ox-busy"))
|
|
||||||
|
|
||||||
title = locate(draft, EC.element_to_be_clickable, (By.CSS_SELECTOR, "div.floating-header"))
|
title = locate(draft, EC.element_to_be_clickable, (By.CSS_SELECTOR, "div.floating-header"))
|
||||||
|
|
||||||
|
# 等待页面加载
|
||||||
|
locate(driver, EC.invisibility_of_element_located, (By.CSS_SELECTOR, ".io-ox-busy"))
|
||||||
|
time.sleep(1)
|
||||||
title.click()
|
title.click()
|
||||||
|
|
||||||
to = locate(draft, EC.element_to_be_clickable, (By.CSS_SELECTOR, "input.token-input.tt-input[tabindex='0']"))
|
to = draft.find_element(By.CSS_SELECTOR, "input.token-input.tt-input[tabindex='0']")
|
||||||
to.send_keys(recipient)
|
to.send_keys(recipient)
|
||||||
|
|
||||||
send = locate(draft, EC.element_to_be_clickable, (By.CSS_SELECTOR, "button[data-action='send']"))
|
send = draft.find_element(By.CSS_SELECTOR, "button[data-action='send']")
|
||||||
send.click()
|
send.click()
|
||||||
|
|
||||||
|
global sent
|
||||||
sent += 1
|
sent += 1
|
||||||
time.sleep(args.interval)
|
time.sleep(args.interval)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'[!!!!] 发生错误:{e}')
|
print(f'[!!!!] 发生错误:{e}')
|
||||||
return 6
|
return 6
|
||||||
|
|
||||||
try:
|
# 等待邮件发送
|
||||||
stale = driver.find_element(By.CSS_SELECTOR, "div.io-ox-mail-compose-window")
|
locate(driver, EC.invisibility_of_element_located, (By.CSS_SELECTOR, "div.mail-send-progress.bottom-message"))
|
||||||
except:
|
|
||||||
continue
|
# 检测页面警告
|
||||||
|
try: alert = driver.find_element(By.CSS_SELECTOR, "div.io-ox-alert.io-ox-alert-error")
|
||||||
|
except: continue
|
||||||
|
|
||||||
alert = locate(driver, EC.element_to_be_clickable, (By.CSS_SELECTOR, "div.io-ox-alert.io-ox-alert-error"))
|
|
||||||
message = alert.text.replace('\n', ' ')
|
message = alert.text.replace('\n', ' ')
|
||||||
|
|
||||||
print(f'[警告] 来自网页:{message}')
|
print(f'[警告] 来自网页:{message}')
|
||||||
|
|
||||||
|
global errors
|
||||||
errors += 1
|
errors += 1
|
||||||
|
|
||||||
|
# 关闭警告
|
||||||
|
button = locate(alert, EC.element_to_be_clickable, (By.CSS_SELECTOR, "button[data-action='close']"))
|
||||||
|
button.click()
|
||||||
|
|
||||||
|
# 获取页面上的过期邮件
|
||||||
|
stale = driver.find_element(By.CSS_SELECTOR, "div.io-ox-mail-compose-window")
|
||||||
|
|
||||||
|
# 关闭过期邮件
|
||||||
button = locate(stale, EC.element_to_be_clickable, (By.CSS_SELECTOR, "button[data-action='close']"))
|
button = locate(stale, EC.element_to_be_clickable, (By.CSS_SELECTOR, "button[data-action='close']"))
|
||||||
button.click()
|
button.click()
|
||||||
|
|
||||||
|
# 删除过期邮件
|
||||||
modal = locate(driver, EC.element_to_be_clickable, (By.CSS_SELECTOR, "div.modal-footer"))
|
modal = locate(driver, EC.element_to_be_clickable, (By.CSS_SELECTOR, "div.modal-footer"))
|
||||||
button = locate(modal, EC.element_to_be_clickable, (By.CSS_SELECTOR, "button[data-action='delete']"))
|
button = locate(modal, EC.element_to_be_clickable, (By.CSS_SELECTOR, "button[data-action='delete']"))
|
||||||
button.click()
|
button.click()
|
||||||
@@ -172,6 +180,7 @@ def locate(driver, condition, locator):
|
|||||||
# 如果遇到过期元素,重新尝试查找
|
# 如果遇到过期元素,重新尝试查找
|
||||||
continue
|
continue
|
||||||
except TimeoutException:
|
except TimeoutException:
|
||||||
|
# 超时错误
|
||||||
raise Exception('操作超时')
|
raise Exception('操作超时')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user