allcode_by.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. import time
  2. import tkinter as tk
  3. from tkinter import ttk, filedialog, messagebox
  4. import json
  5. import os
  6. import threading
  7. import logging
  8. from selenium import webdriver
  9. from selenium.webdriver.common.by import By
  10. from selenium.webdriver.chrome.service import Service
  11. from selenium.webdriver.support.ui import Select
  12. from selenium.webdriver.support import expected_conditions as EC
  13. from selenium.webdriver.support.ui import WebDriverWait
  14. from selenium.common.exceptions import TimeoutException
  15. from utils import abbreviation_to_index
  16. from bit_api import *
  17. from multiprocessing import Process
  18. import datetime
  19. current_time = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
  20. # 设置日志
  21. logging.basicConfig(level=logging.INFO)
  22. logger = logging.getLogger(__name__)
  23. result_logger = logging.getLogger("normal")
  24. # 结果保留日志
  25. logger1 = logging.getLogger('result_log')
  26. logger1.setLevel(logging.INFO)
  27. handler1 = logging.FileHandler("result_log" + ".log")
  28. formatter1 = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
  29. handler1.setFormatter(formatter1)
  30. logger1.addHandler(handler1)
  31. # 自定义日志处理器,用于将日志输出到 GUI 的文本框
  32. class TextHandler(logging.Handler):
  33. def __init__(self, text_widget, adjust_height_callback):
  34. super().__init__()
  35. self.text_widget = text_widget
  36. self.adjust_height_callback = adjust_height_callback
  37. def emit(self, record):
  38. msg = self.format(record)
  39. self.text_widget.insert(tk.END, msg + '\n')
  40. self.text_widget.see(tk.END)
  41. self.adjust_height_callback()
  42. # GUI 类
  43. class AdsDataGUI:
  44. def __init__(self, root):
  45. self.root = root
  46. self.root.title("自动化注册 - BitBrowser")
  47. # 初始化运行状态
  48. self.running = False
  49. self.current_web = None # 用于存储当前 Selenium WebDriver 实例
  50. # 加载保存的配置
  51. self.config_file = "config.json"
  52. self.load_config()
  53. # 参数输入框
  54. self.params = {
  55. "WINDOW_ID": tk.StringVar(value=self.config.get("WINDOW_ID", "5c2216ed3b3e4bf0bc144b5ad0c87a5b")),
  56. "BASE_URL": tk.StringVar(value=self.config.get("BASE_URL", "http://127.0.0.1:54345")),
  57. "API_KEY": tk.StringVar(value=self.config.get("API_KEY", "704daf420f7244d08be51f61c987a232")),
  58. "FILE_PATH": tk.StringVar(value=self.config.get("FILE_PATH", "generated_data.txt")),
  59. "AMOUNT": tk.StringVar(value=self.config.get("AMOUNT", "$501-$1,000")),
  60. "SLEEP_TIME_1": tk.DoubleVar(value=self.config.get("SLEEP_TIME_1", 10.0)), # 验证码等待时间
  61. "SLEEP_TIME_2": tk.DoubleVar(value=self.config.get("SLEEP_TIME_2", 3.0)), # 提交后等待时间
  62. "SLEEP_TIME_3": tk.DoubleVar(value=self.config.get("SLEEP_TIME_3", 10.0)), # 关闭后等待时间
  63. "NO_SANDBOX": tk.BooleanVar(value=self.config.get("NO_SANDBOX", True)),
  64. "DISABLE_DEV_SHM": tk.BooleanVar(value=self.config.get("DISABLE_DEV_SHM", True)),
  65. "START_MAXIMIZED": tk.BooleanVar(value=self.config.get("START_MAXIMIZED", True))
  66. }
  67. # 创建主框架
  68. self.main_frame = ttk.Frame(self.root)
  69. self.main_frame.pack(fill=tk.BOTH, expand=True)
  70. # 创建画布和滚动条
  71. self.canvas = tk.Canvas(self.main_frame)
  72. self.scrollbar = ttk.Scrollbar(self.main_frame, orient=tk.VERTICAL, command=self.canvas.yview)
  73. self.scrollable_frame = ttk.Frame(self.canvas)
  74. self.scrollable_frame.bind(
  75. "<Configure>",
  76. lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all"))
  77. )
  78. self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
  79. self.canvas.configure(yscrollcommand=self.scrollbar.set)
  80. self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
  81. self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
  82. # 创建 GUI 元素(中文界面)
  83. row = 0
  84. tk.Label(self.scrollable_frame, text="自动化注册 - BitBrowser", font=("Arial", 16)).grid(row=row, column=0,
  85. columnspan=3, pady=10)
  86. row += 1
  87. # 参数输入框
  88. labels = [
  89. ("窗口 ID:", self.params["WINDOW_ID"]),
  90. ("API 地址:", self.params["BASE_URL"]),
  91. ("API 密钥:", self.params["API_KEY"]),
  92. ("文件路径:", self.params["FILE_PATH"]),
  93. ("金额范围:", self.params["AMOUNT"]),
  94. ("等待时间 1 (验证码, 秒):", self.params["SLEEP_TIME_1"]),
  95. ("等待时间 2 (提交后, 秒):", self.params["SLEEP_TIME_2"]),
  96. ("等待时间 3 (关闭后, 秒):", self.params["SLEEP_TIME_3"])
  97. ]
  98. for label_text, var in labels:
  99. tk.Label(self.scrollable_frame, text=label_text).grid(row=row, column=0, sticky="e", padx=5, pady=5)
  100. if label_text == "金额范围:":
  101. amount_options = ["$1-$500", "$501-$1,000", "$1,001-$5,000", "超过 $5,000"]
  102. ttk.Combobox(self.scrollable_frame, textvariable=var, values=amount_options, state="readonly").grid(
  103. row=row, column=1, padx=5, pady=5, sticky="ew")
  104. else:
  105. tk.Entry(self.scrollable_frame, textvariable=var).grid(row=row, column=1, padx=5, pady=5, sticky="ew")
  106. if label_text == "文件路径:":
  107. tk.Button(self.scrollable_frame, text="浏览", command=self.browse_file).grid(row=row, column=2, padx=5,
  108. pady=5)
  109. row += 1
  110. tk.Checkbutton(self.scrollable_frame, text="无沙盒模式", variable=self.params["NO_SANDBOX"]).grid(row=row,
  111. column=0,
  112. columnspan=3,
  113. pady=5)
  114. row += 1
  115. tk.Checkbutton(self.scrollable_frame, text="禁用 Dev SHM", variable=self.params["DISABLE_DEV_SHM"]).grid(
  116. row=row, column=0, columnspan=3, pady=5)
  117. row += 1
  118. tk.Checkbutton(self.scrollable_frame, text="启动时最大化", variable=self.params["START_MAXIMIZED"]).grid(
  119. row=row, column=0, columnspan=3, pady=5)
  120. row += 1
  121. self.status_label = tk.Label(self.scrollable_frame, text="状态: 就绪", fg="blue")
  122. self.status_label.grid(row=row, column=0, columnspan=3, pady=10)
  123. row += 1
  124. tk.Label(self.scrollable_frame, text="日志输出:").grid(row=row, column=0, columnspan=3, pady=5)
  125. row += 1
  126. # 日志窗口,初始高度为 0,动态调整
  127. self.log_frame = ttk.Frame(self.scrollable_frame)
  128. self.log_frame.grid(row=row, column=0, columnspan=3, padx=5, pady=5, sticky="nsew")
  129. self.log_text = tk.Text(self.log_frame, height=0, width=60, wrap=tk.WORD)
  130. self.log_scrollbar = ttk.Scrollbar(self.log_frame, orient=tk.VERTICAL, command=self.log_text.yview)
  131. self.log_text.configure(yscrollcommand=self.log_scrollbar.set)
  132. self.log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
  133. self.log_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
  134. row += 1
  135. # 按钮框架
  136. button_frame = ttk.Frame(self.scrollable_frame)
  137. button_frame.grid(row=row, column=0, columnspan=3, pady=10)
  138. tk.Button(button_frame, text="开始", command=self.start_script).pack(side=tk.LEFT, padx=5)
  139. tk.Button(button_frame, text="停止", command=self.stop_script).pack(side=tk.LEFT, padx=5)
  140. tk.Button(button_frame, text="清除日志", command=self.clear_log).pack(side=tk.LEFT, padx=5)
  141. tk.Button(button_frame, text="保存参数", command=self.save_config).pack(side=tk.LEFT, padx=5)
  142. row += 1
  143. # 设置列权重,使输入框宽度自适应
  144. for i in range(3):
  145. self.scrollable_frame.grid_columnconfigure(i, weight=1)
  146. # 设置日志处理器
  147. self.log_handler = TextHandler(self.log_text, self.adjust_log_height)
  148. logger.addHandler(self.log_handler)
  149. # 保存配置时绑定关闭事件
  150. self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
  151. # 调整窗口大小以适应内容
  152. self.root.update_idletasks()
  153. self.root.minsize(self.scrollable_frame.winfo_reqwidth(), self.scrollable_frame.winfo_reqheight())
  154. def adjust_log_height(self):
  155. """动态调整日志框高度"""
  156. content = self.log_text.get("1.0", tk.END).strip()
  157. if not content:
  158. self.log_text.configure(height=0)
  159. else:
  160. lines = content.count('\n') + 1
  161. max_height = 20
  162. new_height = min(lines, max_height)
  163. self.log_text.configure(height=new_height)
  164. def load_config(self):
  165. """加载配置文件"""
  166. self.config = {}
  167. if os.path.exists(self.config_file):
  168. try:
  169. with open(self.config_file, 'r', encoding='utf-8') as f:
  170. self.config = json.load(f)
  171. except Exception as e:
  172. logger.error(f"无法加载配置文件: {str(e)}")
  173. def save_config(self):
  174. """保存配置"""
  175. config = {
  176. "WINDOW_ID": self.params["WINDOW_ID"].get(),
  177. "BASE_URL": self.params["BASE_URL"].get(),
  178. "API_KEY": self.params["API_KEY"].get(),
  179. "FILE_PATH": self.params["FILE_PATH"].get(),
  180. "AMOUNT": self.params["AMOUNT"].get(),
  181. "SLEEP_TIME_1": self.params["SLEEP_TIME_1"].get(),
  182. "SLEEP_TIME_2": self.params["SLEEP_TIME_2"].get(),
  183. "SLEEP_TIME_3": self.params["SLEEP_TIME_3"].get(),
  184. "NO_SANDBOX": self.params["NO_SANDBOX"].get(),
  185. "DISABLE_DEV_SHM": self.params["DISABLE_DEV_SHM"].get(),
  186. "START_MAXIMIZED": self.params["START_MAXIMIZED"].get()
  187. }
  188. try:
  189. with open(self.config_file, 'w', encoding='utf-8') as f:
  190. json.dump(config, f, indent=4, ensure_ascii=False)
  191. messagebox.showinfo("提示", "参数已保存!")
  192. except Exception as e:
  193. logger.error(f"无法保存配置文件: {str(e)}")
  194. messagebox.showerror("错误", f"无法保存参数: {str(e)}")
  195. def on_closing(self):
  196. """关闭窗口时保存配置"""
  197. self.save_config()
  198. self.root.destroy()
  199. def browse_file(self):
  200. """文件选择器"""
  201. file_path = filedialog.askopenfilename(filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")])
  202. if file_path:
  203. self.params["FILE_PATH"].set(file_path)
  204. def clear_log(self):
  205. """清除日志"""
  206. self.log_text.delete(1.0, tk.END)
  207. self.adjust_log_height()
  208. def start_script(self):
  209. if self.running:
  210. messagebox.showinfo("提示", "脚本已经在运行!")
  211. return
  212. self.running = True
  213. self.status_label.config(text="状态: 运行中", fg="green")
  214. threading.Thread(target=self.run_script, daemon=True).start()
  215. def stop_script(self):
  216. self.running = False
  217. self.status_label.config(text="状态: 已停止", fg="red")
  218. # 立即关闭当前浏览器
  219. if self.current_web:
  220. try:
  221. self.current_web.quit()
  222. logger.info("因用户停止脚本,关闭 Selenium 驱动...")
  223. except Exception as e:
  224. logger.error(f"关闭 Selenium 驱动失败: {str(e)}")
  225. self.current_web = None
  226. def run_script(self):
  227. try:
  228. logger.info("开始运行脚本...")
  229. datas = read_txt_file(self.params["FILE_PATH"].get())
  230. if not datas:
  231. self.status_label.config(text="状态: 错误 - 文件未找到", fg="red")
  232. logger.error("文件未找到或为空")
  233. return
  234. logger.info(f"从文件中读取了 {len(datas)} 条记录")
  235. for data in datas:
  236. if not self.running:
  237. logger.info("用户停止了脚本")
  238. break
  239. self.status_label.config(text=f"状态: 正在处理 {data[0]}", fg="green")
  240. logger.info(f"处理记录: {data}")
  241. # 添加重试机制
  242. max_retries = 3
  243. attempt_success = False
  244. for attempt in range(max_retries):
  245. if not self.running:
  246. logger.info("用户停止了脚本")
  247. break
  248. try:
  249. result = start_Ads_data(
  250. self,
  251. data,
  252. window_id=self.params["WINDOW_ID"].get(),
  253. sleep_times={
  254. "sleep1": self.params["SLEEP_TIME_1"].get(),
  255. "sleep2": self.params["SLEEP_TIME_2"].get(),
  256. "sleep3": self.params["SLEEP_TIME_3"].get()
  257. },
  258. chrome_options={
  259. "no_sandbox": self.params["NO_SANDBOX"].get(),
  260. "disable_dev_shm": self.params["DISABLE_DEV_SHM"].get(),
  261. "start_maximized": self.params["START_MAXIMIZED"].get()
  262. },
  263. amount=self.params["AMOUNT"].get(), API_KEY=self.params["API_KEY"].get()
  264. )
  265. if result:
  266. logger.info("操作成功!")
  267. # 删除数据
  268. with open(self.params["FILE_PATH"].get(), "r") as f:
  269. lines = f.readlines()
  270. # 保留不匹配的行
  271. filtered_lines = [line for line in lines if data[0] not in line]
  272. with open(self.params["FILE_PATH"].get(), 'w') as f:
  273. f.writelines(filtered_lines)
  274. attempt_success = True
  275. break # 成功则跳出循环
  276. else:
  277. # 返回 False也跳出循环,并记录
  278. logger.warning(f"查询超时已记录")
  279. break
  280. except Exception as e:
  281. if not self.running:
  282. logger.info("用户停止了脚本")
  283. break
  284. if attempt < max_retries - 1:
  285. logger.warning(f"尝试 {attempt + 1} 失败: {str(e)},等待 10 秒后重试...")
  286. time.sleep(10)
  287. else:
  288. raise e
  289. if not attempt_success and attempt == max_retries - 1:
  290. # 三次重试之后失败
  291. logger1.info(f"finally{data}注册失败")
  292. logger.info("完成一条记录,进入下一条记录")
  293. self.status_label.config(text="状态: 已完成", fg="blue")
  294. logger.info("脚本运行完成")
  295. except Exception as e:
  296. self.status_label.config(text=f"状态: 错误 - {str(e)}", fg="red")
  297. logger.error(f"运行脚本时出错: {str(e)}")
  298. finally:
  299. self.running = False
  300. self.current_web = None
  301. def start_Ads_data(gui, data, window_id, sleep_times, chrome_options, amount, API_KEY):
  302. # 处理表单填写
  303. # 使用 BitBrowser 窗口 ID
  304. # res = openBrowser(window_id)
  305. #
  306. # # 调试:打印 openBrowser 的返回值
  307. # logger.info(f"openBrowser Response: {res}")
  308. #
  309. # # 检查返回值是否包含 'data' 键
  310. # if 'data' not in res:
  311. # logger.error("BitBrowser API 返回中没有 'data' 键")
  312. # raise Exception("BitBrowser API 返回中没有 'data' 键")
  313. #
  314. # driverPath = res['data']['driver']
  315. # debuggerAddress = res['data']['http']
  316. #
  317. # if res["success"] is True:
  318. # logger.info("启动成功,返回信息")
  319. # else:
  320. # logger.error(f"{window_id}启动失败")
  321. # raise Exception("启动失败")
  322. #
  323. # chrome_opts = webdriver.ChromeOptions()
  324. # chrome_opts.add_experimental_option("debuggerAddress", debuggerAddress)
  325. #
  326. # if chrome_options["no_sandbox"]:
  327. # chrome_opts.add_argument('--no-sandbox')
  328. # if chrome_options["disable_dev_shm"]:
  329. # chrome_opts.add_argument('--disable-dev-shm-usage')
  330. # if chrome_options["start_maximized"]:
  331. # chrome_opts.add_argument('--start-maximized')
  332. #
  333. # chrome_service = Service(driverPath)
  334. # web = webdriver.Chrome(service=chrome_service, options=chrome_opts)
  335. # web.implicitly_wait(30)
  336. #
  337. # # 将 web 实例保存到 GUI 对象,以便在停止时关闭
  338. # gui.current_web = web
  339. #
  340. # web.get("https://claimform.savingsclubsettlement.com/consumerb-claimants")
  341. # original_window = web.current_window_handle
  342. # WebDriverWait(web, 30).until(EC.presence_of_element_located((By.TAG_NAME, 'body')))
  343. # logger.info(f"当前页面标题: {web.title}")
  344. web = start_ADS(window_id, chrome_options, gui, sleep_times, API_KEY)
  345. # 滑动到页面的底部
  346. web.execute_script("window.scrollTo(0, document.body.scrollHeight);")
  347. time.sleep(sleep_times["sleep1"])
  348. logger.info("等待验证码识别")
  349. try:
  350. iframe = WebDriverWait(web, 10).until(
  351. EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[src*='google.com/recaptcha']"))
  352. )
  353. except TimeoutException:
  354. logger.error("未找到reCAPTCHA iframe")
  355. raise Exception("未找到reCAPTCHA iframe")
  356. max_attempts = 10 # 最大尝试次数
  357. attempts = 0 # 当前尝试计数器
  358. while True:
  359. try:
  360. WebDriverWait(web, 10).until(
  361. lambda d: d.find_element(By.ID, 'g-recaptcha-response').get_attribute('value') != ''
  362. )
  363. logger.info("reCAPTCHA验证成功")
  364. break
  365. except TimeoutException:
  366. attempts += 1
  367. logger.warning("验证未完成或失败")
  368. if attempts >= max_attempts:
  369. logger.info("达到最大尝试次数,刷新页面...")
  370. web.refresh()
  371. attempts = 0 # 重置计数器
  372. finally:
  373. web.switch_to.default_content()
  374. web.switch_to.default_content()
  375. web.find_element(By.XPATH, "//input[@type='text']").send_keys(data[1])
  376. web.find_element(By.ID, "street1").send_keys(data[2])
  377. web.find_element(By.ID, "city").send_keys(data[3])
  378. time.sleep(1)
  379. Select(web.find_element(By.XPATH,
  380. "(.//*[normalize-space(text()) and normalize-space(.)='*'])[5]/preceding::select[1]")).select_by_index(
  381. abbreviation_to_index[data[4]])
  382. web.find_element(By.ID, "zip").send_keys(data[5])
  383. time.sleep(1)
  384. web.find_element(By.ID, "email").send_keys(data[0])
  385. web.find_element(By.XPATH, "//input[@type='checkbox']").click()
  386. web.find_element(By.XPATH, f"//input[@value='{amount}']").click()
  387. web.find_element(By.ID, "signature").send_keys(data[1])
  388. submit_button = WebDriverWait(web, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[@type='submit']")))
  389. submit_button.click()
  390. logger.info("填写表单完成,提交并开始验证")
  391. # 验证提取是否成功
  392. result = check_submission_success(data, web)
  393. time.sleep(sleep_times["sleep2"])
  394. web.delete_all_cookies()
  395. web.execute_script("window.localStorage.clear();")
  396. web.execute_script("window.sessionStorage.clear();")
  397. web.quit()
  398. time.sleep(sleep_times["sleep3"])
  399. # 使用 BitBrowser 窗口 ID
  400. closeBrowser(window_id)
  401. # 添加延迟,确保窗口完全关闭
  402. logger.info("等待窗口完全关闭...")
  403. time.sleep(sleep_times["sleep3"])
  404. logger.info("完成一次填表循环")
  405. return result
  406. def start_ADS(window_id, chrome_options, gui, sleep_times, API_KEY):
  407. # 开启窗口,打开页面,加载插件号
  408. while True:
  409. try:
  410. res = openBrowser(window_id)
  411. # 调试:打印 openBrowser 的返回值
  412. logger.info(f"openBrowser Response: {res}")
  413. # 检查返回值是否包含 'data' 键
  414. if 'data' not in res:
  415. logger.error("BitBrowser API 返回中没有 'data' 键")
  416. raise Exception("BitBrowser API 返回中没有 'data' 键")
  417. driverPath = res['data']['driver']
  418. debuggerAddress = res['data']['http']
  419. if res["success"] is True:
  420. logger.info("启动成功,返回信息")
  421. else:
  422. logger.error(f"{window_id}启动失败")
  423. raise Exception("启动失败")
  424. chrome_opts = webdriver.ChromeOptions()
  425. chrome_opts.add_experimental_option("debuggerAddress", debuggerAddress)
  426. if chrome_options["no_sandbox"]:
  427. chrome_opts.add_argument('--no-sandbox')
  428. if chrome_options["disable_dev_shm"]:
  429. chrome_opts.add_argument('--disable-dev-shm-usage')
  430. if chrome_options["start_maximized"]:
  431. chrome_opts.add_argument('--start-maximized')
  432. chrome_service = Service(driverPath)
  433. web = webdriver.Chrome(service=chrome_service, options=chrome_opts)
  434. web.implicitly_wait(60)
  435. # 将 web 实例保存到 GUI 对象,以便在停止时关闭
  436. gui.current_web = web
  437. logger.info("加载插件")
  438. web.get(f"https://nopecha.com/setup#{API_KEY}")
  439. web.get("https://claimform.savingsclubsettlement.com/consumerb-claimants")
  440. original_window = web.current_window_handle
  441. WebDriverWait(web, 10).until(EC.presence_of_element_located((By.TAG_NAME, 'body')))
  442. logger.info(f"当前页面标题: {web.title}")
  443. break
  444. except Exception as e:
  445. logger.info(f"加载页面失败{str(e)},将重启窗口{window_id}")
  446. # 关闭窗口
  447. closeBrowser(window_id)
  448. time.sleep(sleep_times["sleep3"])
  449. return web
  450. def check_submission_success(data, web):
  451. # 验证是否是否提交成功得参考号
  452. try:
  453. # 等待成功标题出现
  454. WebDriverWait(web, 30).until(
  455. EC.visibility_of_element_located((By.XPATH, "//h2[contains(., 'THANK YOU FOR SUBMITTING')]"))
  456. )
  457. # 获取参考号和日期
  458. ref_number = web.find_element(By.XPATH, "//p[contains(., 'Your Reference Number is')]/b").text
  459. # submission_date = web.find_element(By.XPATH, "//p[contains(., 'submitted on')]/b").text
  460. logger1.info(", ".join(data) + "提交成功参考号为:" + ref_number)
  461. return True
  462. except Exception as e:
  463. logger.warning({str(e)})
  464. logger.warning(", ".join(data) + "验证失败")
  465. logger1.info(", ".join(data) + "提交后查询参考号失败")
  466. # 这里不抛异常
  467. return False
  468. def read_txt_file(file_path):
  469. data = []
  470. try:
  471. with open(file_path, 'r', encoding='utf-8') as file:
  472. for line in file:
  473. cleaned_line = line.strip()
  474. if not cleaned_line:
  475. continue
  476. fields = cleaned_line.split('\t')
  477. if len(fields) != 6:
  478. logger.warning(f"第 {len(data) + 1} 行字段数量异常: {len(fields)}")
  479. continue
  480. data.append(fields)
  481. except FileNotFoundError:
  482. logger.error(f"文件 {file_path} 未找到")
  483. return None
  484. except Exception as e:
  485. logger.error(f"读取文件时发生错误: {str(e)}")
  486. return None
  487. return data
  488. if __name__ == '__main__':
  489. root = tk.Tk()
  490. app = AdsDataGUI(root)
  491. root.mainloop()
  492. # 打包成exe命令,会打包所有python包
  493. # Pyinstaller -F -w -i pp.ico allcode_by.py
  494. # 5c2216ed3b3e4bf0bc144b5ad0c87a5b
  495. # fd2014bb64b142a5a553d275567f573c