update: created main loop & pivot to wxPython

This commit is contained in:
2025-07-31 14:33:18 +08:00
parent 4173ff9b5a
commit 6597ced3cb
2 changed files with 232 additions and 214 deletions

Binary file not shown.

View File

@@ -2,6 +2,7 @@ import unicodedata
import argparse
import pandas
import time
import wx
from selenium import webdriver
from selenium.common.exceptions import StaleElementReferenceException, TimeoutException
@@ -11,20 +12,18 @@ from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.remote.webelement import WebElement
from tkinter import Tk, filedialog
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from nameparser import HumanName
parser = argparse.ArgumentParser(description="邮件批量发送脚本")
parser.add_argument('input', nargs='?')
parser.add_argument('url', nargs='?', default='https://id.ionos.fr/identifier')
parser.add_argument('--column-address', type=str, nargs='?', default='邮箱')
parser.add_argument('--column-name', type=str, nargs='?', default='主要联系人')
parser.add_argument('--column-code', type=str, nargs='?', default='客户编号')
parser.add_argument('--column-sent', type=str, nargs='?', default='已发送')
parser.add_argument('-u', '--url', type=str, nargs='?', default='https://id.ionos.fr/identifier')
parser.add_argument('-a', '--address', type=str, required=True)
parser.add_argument('-p', '--password', type=str, required=True)
parser.add_argument('-a', '--address', type=str, nargs='?', default='')
parser.add_argument('-p', '--password', type=str, nargs='?', default='')
parser.add_argument('-t', '--timeout', type=int, nargs='?', default=60)
parser.add_argument('-i', '--interval', type=int, nargs='?', default=10)
parser.add_argument('-m', '--max-occurrence', type=int, nargs='?', default=5)
@@ -77,36 +76,18 @@ greetings = [
]
def main():
if not args.input:
root = Tk()
root.withdraw()
args.input = filedialog.askopenfilename(defaultextension='xlsx')
print(f'[信息] 正在读取数据:{args.input}')
try:
workbook = pandas.read_excel(args.input)
data = workbook.where(pandas.notnull(workbook), None).to_dict(orient='list')
recipients = data.get(args.column_address, [])
except Exception as e:
print(f'[!!!!] 读取数据表失败:{e}')
return 1
limit = len(recipients)
names = data.get(args.column_name, [None] * limit)
codes = data.get(args.column_code, [None] * limit)
sents = data.setdefault(args.column_sent, [None] * limit)
print(f'[信息] 已读取联系人信息共 {limit}')
if limit == 0: return 0
print('[信息] 程序初始化中...')
app = wx.App(None)
print('[信息] 正在启动 Chrome 自动化实例')
try:
opts = webdriver.ChromeOptions()
opts.add_experimental_option("excludeSwitches", ["enable-logging"])
driver = webdriver.Chrome(opts)
driver.set_page_load_timeout(args.timeout)
except Exception as e:
print(f'[!!!!] 初始化时发生了错误:{e}')
return 2
return 1
def locate(selector, condition=EC.presence_of_element_located, parent=driver) -> WebElement:
for attempt in range(args.retry):
@@ -176,6 +157,7 @@ def main():
try: click("#selectAll")
except: pass
if args.address and args.password:
try:
print(f'[信息] 正在登陆 {args.address}')
username = locate("#username")
@@ -188,6 +170,8 @@ def main():
except Exception as e:
print(f'[!!!!] 登录时发生了错误:{e}')
return 4
else:
print('[信息] 请在页面上输入账户凭据')
while True:
try:
@@ -202,6 +186,35 @@ def main():
except:
time.sleep(args.interval)
while True:
try:
print('[信息] 请选择数据源')
dialog = wx.FileDialog(None, 'Open', wildcard='*.xlsx', style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
if dialog.ShowModal() == wx.ID_OK:
filepath = dialog.GetPath()
print(f'[信息] 正在读取数据:{filepath}')
else:
print('[警告] 操作取消')
return 0
workbook = pandas.read_excel(filepath)
data = workbook.where(pandas.notnull(workbook), None).to_dict(orient='list')
recipients = data.get(args.column_address, [])
except Exception as e:
print(f'[警告] 读取数据表失败:{e}')
continue
finally:
dialog.Destroy()
limit = len(recipients)
names = data.get(args.column_name, [None] * limit)
codes = data.get(args.column_code, [None] * limit)
sents = data.setdefault(args.column_sent, [None] * limit)
print(f'[信息] 已读取联系人信息共 {limit}')
if limit == 0: continue
try:
# 打开草稿箱
click("li[data-id='default0/Brouillons']", condition=EC.presence_of_element_located)
@@ -237,13 +250,11 @@ def main():
while command is None:
match input('\n[????] 请选择 (留空取消操作): ').strip():
case keys if not keys:
command = -1
print('[信息] 操作取消')
return 0
case keys if keys.isdigit():
number = int(keys)
if number < len(greetings): command = number
if command < 0:
print('[信息] 已取消发送')
exit()
global date
date = datetime.now()
@@ -372,10 +383,17 @@ def main():
elif key in ['S', 's']: break
else: active = False
if input('[????] 是否保存到文件?确定 (y) / 取消 (N): ') in ['Y', 'y']:
print(f'[信息] 正在写入文件:{args.input}')
progress = index / limit * 100
print('[信息] 当前进度:%.2f %%' % progress)
key = input('[????] 继续运行 (C) / 保存并退出 (s) / 不保存退出 (w): ')
if key in ['W', 'w']: return 0
elif key in ['S', 's']: break
else: continue
print(f'[信息] 正在写入文件:{filepath}')
try:
pandas.DataFrame.from_dict(data).to_excel(args.input, index=False, sheet_name='Sheet1')
pandas.DataFrame.from_dict(data).to_excel(filepath, index=False, sheet_name='Sheet1')
except Exception as e:
print(f'[警告] 写入文件时发生了错误:{e}')
return 6