update: mail content check
This commit is contained in:
95
邮件批量发送脚本.py
95
邮件批量发送脚本.py
@@ -6,7 +6,6 @@ import time
|
|||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
from selenium.common.exceptions import StaleElementReferenceException, TimeoutException
|
from selenium.common.exceptions import StaleElementReferenceException, TimeoutException
|
||||||
from selenium.webdriver.common.action_chains import ActionChains
|
from selenium.webdriver.common.action_chains import ActionChains
|
||||||
from selenium.webdriver.common.keys import Keys
|
|
||||||
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
|
||||||
@@ -146,11 +145,9 @@ def main():
|
|||||||
except TimeoutException: continue
|
except TimeoutException: continue
|
||||||
except: break
|
except: break
|
||||||
|
|
||||||
def keyin(element: WebElement, string: str):
|
def keyin(element: WebElement, value):
|
||||||
for char in string:
|
try: element.send_keys(value)
|
||||||
click(element)
|
except: driver.execute_script(f"arguments[0].value = arguments[1];", element, value)
|
||||||
element.send_keys(Keys.END)
|
|
||||||
element.send_keys(char)
|
|
||||||
|
|
||||||
def ready(driver, predicate):
|
def ready(driver, predicate):
|
||||||
try:
|
try:
|
||||||
@@ -195,8 +192,10 @@ def main():
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
driver.find_element(By.CSS_SELECTOR, "#io-ox-core")
|
driver.find_element(By.CSS_SELECTOR, "#io-ox-core")
|
||||||
print(f'[信息] 已登录')
|
loader = driver.find_element(By.CSS_SELECTOR, "#background-loader")
|
||||||
break
|
if not loader.is_displayed():
|
||||||
|
print(f'[信息] 已登录')
|
||||||
|
break
|
||||||
except:
|
except:
|
||||||
time.sleep(args.interval)
|
time.sleep(args.interval)
|
||||||
|
|
||||||
@@ -226,7 +225,7 @@ def main():
|
|||||||
if rate > 8.33: print('[警告] 当前发送速率已超出限制 8.33 封/分钟')
|
if rate > 8.33: print('[警告] 当前发送速率已超出限制 8.33 封/分钟')
|
||||||
|
|
||||||
print(f'[信息] 当前时区:{args.timezone}')
|
print(f'[信息] 当前时区:{args.timezone}')
|
||||||
print(f'[信息] 已读取问候语 {len(greetings)} 条:', end='\n\n')
|
print(f'[信息] 已读取可用问候语 {len(greetings)} 条:', end='\n\n')
|
||||||
|
|
||||||
for index, item in enumerate(greetings):
|
for index, item in enumerate(greetings):
|
||||||
print(f'\t[{index}] {item.get('locale')}', end=' ')
|
print(f'\t[{index}] {item.get('locale')}', end=' ')
|
||||||
@@ -255,6 +254,7 @@ def main():
|
|||||||
global errors
|
global errors
|
||||||
global sent
|
global sent
|
||||||
|
|
||||||
|
attempt = 0
|
||||||
current = index
|
current = index
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
@@ -282,6 +282,8 @@ def main():
|
|||||||
|
|
||||||
while active:
|
while active:
|
||||||
try:
|
try:
|
||||||
|
clean = True
|
||||||
|
attempt += 1
|
||||||
print(f'[信息] 正在发送:{recipient}')
|
print(f'[信息] 正在发送:{recipient}')
|
||||||
click("button[aria-label='Edit copy']")
|
click("button[aria-label='Edit copy']")
|
||||||
|
|
||||||
@@ -295,8 +297,10 @@ def main():
|
|||||||
case hour if 18 <= hour < 21: registry = selection.get('registry')[2]
|
case hour if 18 <= hour < 21: registry = selection.get('registry')[2]
|
||||||
case _: registry = None
|
case _: registry = None
|
||||||
|
|
||||||
action = ActionChains(driver, 5000)
|
clean = False
|
||||||
action.send_keys(registry or selection.get('default'))
|
iframe = driver.switch_to.active_element
|
||||||
|
action = ActionChains(driver)
|
||||||
|
hello: str = registry or selection.get('default')
|
||||||
|
|
||||||
if name is not None and (name := str(name).strip()) and not contains_non_latin_alphabet(name):
|
if name is not None and (name := str(name).strip()) and not contains_non_latin_alphabet(name):
|
||||||
const = config.CONSTANTS
|
const = config.CONSTANTS
|
||||||
@@ -305,10 +309,14 @@ def main():
|
|||||||
parts = HumanName(name, const)
|
parts = HumanName(name, const)
|
||||||
parts.capitalize()
|
parts.capitalize()
|
||||||
person = ' '.join(filter(None, [parts.title, parts.first or parts.middle or parts.last]))
|
person = ' '.join(filter(None, [parts.title, parts.first or parts.middle or parts.last]))
|
||||||
action.send_keys(Keys.SPACE).send_keys(person)
|
hello = ' '.join([hello, person])
|
||||||
|
|
||||||
action.send_keys(',')
|
hello += ','
|
||||||
action.perform()
|
action.send_keys(hello).perform()
|
||||||
|
|
||||||
|
if items := iframe.find_elements(By.XPATH, f'//*[contains(text(), "{hello}")]'):
|
||||||
|
target = items[0]
|
||||||
|
clean = target.text == hello
|
||||||
|
|
||||||
driver.switch_to.default_content()
|
driver.switch_to.default_content()
|
||||||
wrapper = locate("div.io-ox-mail-compose-window div[data-extension-id='to'] > div.mail-input")
|
wrapper = locate("div.io-ox-mail-compose-window div[data-extension-id='to'] > div.mail-input")
|
||||||
@@ -317,35 +325,50 @@ def main():
|
|||||||
# 填入收件人
|
# 填入收件人
|
||||||
click(wrapper)
|
click(wrapper)
|
||||||
keyin(to, recipient)
|
keyin(to, recipient)
|
||||||
# 发送邮件
|
|
||||||
click("div.io-ox-mail-compose-window button[data-action='send']")
|
|
||||||
|
|
||||||
# 检测页面警告
|
if to.get_attribute('value') != recipient:
|
||||||
try:
|
print(f'[警告] ({attempt}) 检测到收件人地址不正确,正在重试...')
|
||||||
wait = WebDriverWait(driver, timeout=args.interval)
|
elif not clean:
|
||||||
alert = wait.until(lambda x: x.find_element(By.CSS_SELECTOR, "div.io-ox-alert.io-ox-alert-error"))
|
print(f'[警告] ({attempt}) 检测到邮件内容不正确,正在重试...')
|
||||||
except TimeoutException:
|
else:
|
||||||
sents[current] = '✔'
|
# 发送邮件
|
||||||
occurrence[0] += 1
|
click("div.io-ox-mail-compose-window button[data-action='send']")
|
||||||
sent += 1
|
# 检测页面警告
|
||||||
break
|
try:
|
||||||
|
wait = WebDriverWait(driver, timeout=args.interval)
|
||||||
|
alert = wait.until(lambda x: x.find_element(By.CSS_SELECTOR, "div.io-ox-alert.io-ox-alert-error"))
|
||||||
|
|
||||||
errors += 1
|
message = alert.text.replace('\n', ' ')
|
||||||
message = alert.text.replace('\n', ' ')
|
if not message: print(f'[警告] 程序异常。请保持页面在前台显示,避免最小化')
|
||||||
print(f'[警告] 来自网页:{message}')
|
else: print(f'[警告] ({attempt}): {message}')
|
||||||
|
|
||||||
# 关闭警告
|
# 关闭警告
|
||||||
click("div.io-ox-alert.io-ox-alert-error button[data-action='close']")
|
click("div.io-ox-alert.io-ox-alert-error button[data-action='close']")
|
||||||
|
except TimeoutException:
|
||||||
|
sents[current] = '✔'
|
||||||
|
occurrence[0] += 1
|
||||||
|
sent += 1
|
||||||
|
break
|
||||||
|
|
||||||
while mails := driver.find_elements(By.CSS_SELECTOR, "div.io-ox-mail-compose-window"):
|
while mails := driver.find_elements(By.CSS_SELECTOR, "div.io-ox-mail-compose-window"):
|
||||||
# 关闭过期邮件
|
try:
|
||||||
try: click("button[data-action='close']", parent=mails[0])
|
# 关闭过期邮件
|
||||||
except: continue
|
click("button[data-action='close']", parent=mails[0])
|
||||||
# 删除过期邮件
|
# 删除过期邮件
|
||||||
click("div.modal-footer button[data-action='delete']")
|
click("div.modal-footer button[data-action='delete']")
|
||||||
break
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if attempt < args.retry:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
print('[警告] 已超出最大重试上限')
|
||||||
|
errors += 1
|
||||||
|
break
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print('[信息] 程序中断')
|
print('[信息] 程序中断')
|
||||||
|
active = False
|
||||||
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'[警告] 发生错误:{e}')
|
print(f'[警告] 发生错误:{e}')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user