import time import threading import queue import tkinter as tk from tkinter import ttk, scrolledtext import os import tempfile import ssl import urllib3 import requests requests.packages.urllib3.disable_warnings() from selenium import webdriver from selenium.webdriver.common.by import By from selenium.common.exceptions import NoSuchElementException, TimeoutException, WebDriverException from webdriver_manager.microsoft import EdgeChromiumDriverManager from webdriver_manager.chrome import ChromeDriverManager from webdriver_manager.firefox import GeckoDriverManager OFF = "OFF" driver = None def add_log(log_text, message): timestamp = time.strftime("%H:%M:%S", time.localtime()) log_text.insert(tk.END, f"[{timestamp}] {message}\n") log_text.see(tk.END) log_text.update() def login(driver, username, password, q, device_type=None): try: q.put("正在打开网关登录页面...") driver.get("http://192.168.1.1") time.sleep(2) q.put(f"正在输入用户名: {username}") login_username = driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/div/table/tbody/tr[1]/td/input") login_username.clear() login_username.send_keys(username) q.put("正在输入密码...") login_password = driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/div/table/tbody/tr[2]/td/input") login_password.clear() login_password.send_keys(password) q.put("正在点击登录按钮...") login_input = driver.find_element(By.XPATH, "/html/body/div[1]/div[2]/div/table/tbody/tr[4]/td/input[1]") login_input.click() time.sleep(3) q.put("登录成功!") return True except Exception as e: q.put(f"登录失败: {str(e)}") return False def get_pon_info(driver, q): try: q.put("正在获取PON信息...") zt_wlc = driver.find_element(By.XPATH, "/html/body/div/div[1]/div[2]/div[2]/div[3]/table/tbody/tr/td/span[2]/a") zt_wlc.click() time.sleep(1) zt_wlc_pon = driver.find_element(By.XPATH, "/html/body/div/div[3]/div[1]/p[3]/a") zt_wlc_pon.click() time.sleep(1) driver.get("http://192.168.1.1/html/amp/opticinfo/e8ceponlink_user.asp") time.sleep(2) zt_wlc_pon_jsggl = driver.find_element(By.XPATH, '//*[@id="ReceivePower"]') jsggl = zt_wlc_pon_jsggl.text q.put(f"接收光功率原始值: [{jsggl}]") if "未连接光纤状态" in jsggl: q.put("警告:未连接光纤状态") else: q.put(f"接收光功率: {jsggl}") q.put("光纤状态正常") return True except Exception as e: q.put(f"获取PON信息失败: {str(e)}") return False def set_reboot(driver, q): try: q.put("正在设置自动重启...") driver.get("http://192.168.1.1/html/ssmp/scheduledrestart/Scheduledrestart.asp") time.sleep(2) reboot_element = driver.find_element(By.XPATH, '//*[@id="rebootChEnable"]') reboot_state = reboot_element.is_selected() if not reboot_state: reboot_element.click() q.put("已启用定时重启") time.sleep(1) reboot_days = ['repeat_day1', 'repeat_day2', 'repeat_day3', 'repeat_day4', 'repeat_day5', 'repeat_day6', 'repeat_day7'] for i, day_id in enumerate(reboot_days): day_element = driver.find_element(By.XPATH, f'//*[@id="{day_id}"]') if i == 0: if not day_element.is_selected(): day_element.click() q.put(f"已选择周一") else: if day_element.is_selected(): day_element.click() q.put(f"已取消选择周{i+1}") reboot_save = driver.find_element(By.XPATH, '//*[@id="applyButton"]') reboot_save.click() time.sleep(2) q.put("自动重启设置完成") return True except Exception as e: q.put(f"设置自动重启失败: {str(e)}") return False def get_device_type(driver, q): try: # 识别设备类型 # 根据登录页面锁定设备的大致类型 q.put("正在识别设备类型...") # 暂时模拟 return None except NoSuchElementException: return None except Exception as e: return e def register_loid(driver, code, q): try: q.put("正在进行LOID注册...") driver.get("http://192.168.1.1/loidreg.asp") time.sleep(2) code_element = driver.find_element(By.XPATH, '//*[@id="PwdValue"]') code_element.clear() code_element.send_keys(code) q.put(f"已输入注册码: {code}") enter_code = driver.find_element(By.XPATH, '//*[@id="setReg"]') enter_code.click() time.sleep(2) q.put("注册提交成功,等待系统处理...") return True except Exception as e: q.put(f"注册失败: {str(e)}") return False def set_wifi_name_and_password(driver, q, wifi_name, wifi_password, update_name=True, update_password=True): try: q.put("正在设置WIFI...") driver.get("http://192.168.1.1/html/amp/wlanbasic/e8cWlanBasic.asp?2G") time.sleep(2) if update_name: wifi_name_element = driver.find_element(By.XPATH, '//*[@id="WlanSsid_text"]') wifi_name_element.clear() wifi_name_element.send_keys("CMCC-%s" % wifi_name) q.put(f"已设置2.4G WiFi名称: CMCC-{wifi_name}") else: q.put("跳过2.4G WiFi名称修改") if update_password: wifi_password_element = driver.find_element(By.XPATH, '//*[@id="WlanPassword_password"]') wifi_password_element.clear() wifi_password_element.send_keys(wifi_password) q.put("已设置2.4G WiFi密码") else: q.put("跳过2.4G WiFi密码修改") save_2g_wifi_element = driver.find_element(By.XPATH, '//*[@id="Save_button"]') save_2g_wifi_element.click() time.sleep(2) driver.get("http://192.168.1.1/html/amp/wlanbasic/e8cWlanBasic.asp?5G") time.sleep(2) if update_name: wifi_name_element = driver.find_element(By.XPATH, '//*[@id="WlanSsid_text"]') wifi_name_element.clear() wifi_name_element.send_keys("CMCC-%s-5G" % wifi_name) q.put(f"已设置5G WiFi名称: CMCC-{wifi_name}-5G") else: q.put("跳过5G WiFi名称修改") if update_password: wifi_password_element = driver.find_element(By.XPATH, '//*[@id="WlanPassword_password"]') wifi_password_element.clear() wifi_password_element.send_keys(wifi_password) q.put("已设置5G WiFi密码") else: q.put("跳过5G WiFi密码修改") save_5g_wifi_element = driver.find_element(By.XPATH, '//*[@id="Save_button"]') save_5g_wifi_element.click() time.sleep(2) q.put("WIFI设置完成") return True except Exception as e: q.put(f"设置WIFI失败: {str(e)}") return False def set_wifi_state(driver, q, wifi_state): try: action = "启用" if wifi_state else "关闭" q.put(f"正在{action}无线网...") driver.get("http://192.168.1.1/html/amp/wlanbasic/cmccWlanSwitch.asp") time.sleep(2) wifi_state_element = driver.find_element(By.XPATH, '//*[@id="WlanEnable_checkbox"]') wifi_is_selected = wifi_state_element.is_selected() if wifi_state != wifi_is_selected: wifi_state_element.click() q.put(f"已{action}无线网") time.sleep(1) else: q.put("当前设置正确无需修改!") return True except Exception as e: q.put(f"设置WiFi状态失败: {str(e)}") return False def run_automation(username, password, code, wifi_state, wifi_name, wifi_password, update_wifi_name, update_wifi_password, browser_choice, log_text, status_label, start_button): global driver q = queue.Queue() def worker(): global driver try: q.put(f"正在启动浏览器 ({browser_choice})...") try: q.put(f"正在检查{browser_choice}浏览器驱动...") ssl._create_default_https_context = ssl._create_unverified_context os.environ['WDM_LOCAL'] = '1' os.environ['WDM_SSL_VERIFY'] = '0' wdm_cache_dir = os.path.join(tempfile.gettempdir(), "router_tool_wdm") os.environ['WDM_CACHE_DIR'] = wdm_cache_dir os.makedirs(wdm_cache_dir, exist_ok=True) q.put(f"驱动缓存目录: {wdm_cache_dir}") import shutil for item in os.listdir(wdm_cache_dir): item_path = os.path.join(wdm_cache_dir, item) if os.path.isdir(item_path) and ('html' in item.lower() or 'DOCTYPE' in item or len(item) > 100): shutil.rmtree(item_path) q.put(f"清理无效缓存目录: {item}") if browser_choice == "Chrome": driver_path = ChromeDriverManager().install() q.put(f"Chrome驱动已安装: {driver_path}") driver = webdriver.Chrome() elif browser_choice == "Firefox": driver_path = GeckoDriverManager().install() q.put(f"Firefox驱动已安装: {driver_path}") from selenium.webdriver.firefox.service import Service as FirefoxService from selenium.webdriver.firefox.options import Options as FirefoxOptions options = FirefoxOptions() firefox_binaries = [ r"C:\Program Files\Mozilla Firefox\firefox.exe", r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe", ] for fb in firefox_binaries: if os.path.isfile(fb): options.binary_location = fb q.put(f"使用Firefox浏览器: {fb}") break service = FirefoxService(executable_path=driver_path) driver = webdriver.Firefox(service=service, options=options) else: driver_path = EdgeChromiumDriverManager().install() q.put(f"Edge驱动已安装: {driver_path}") driver = webdriver.Edge() q.put("浏览器启动成功") except Exception as e: q.put(f"驱动安装失败,尝试手动查找驱动: {str(e)}") try: if browser_choice == "Chrome": import glob as _glob chrome_driver_paths = [ r"C:\Program Files\Google\Chrome\Application\chromedriver.exe", r"C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe", os.path.join(os.path.expanduser("~"), ".wdm", "drivers", "chromedriver", "win64"), os.path.join(tempfile.gettempdir(), "router_tool_wdm"), ] found = None for p in chrome_driver_paths: if os.path.isdir(p): for f in os.listdir(p): if "chromedriver" in f.lower() and f.endswith(".exe"): found = os.path.join(p, f) break if found: break elif os.path.isfile(p): found = p; break if found: q.put(f"找到Chrome驱动: {found}") driver = webdriver.Chrome(found) else: driver = webdriver.Chrome() elif browser_choice == "Firefox": from selenium.webdriver.firefox.service import Service as FirefoxService from selenium.webdriver.firefox.options import Options as FirefoxOptions options = FirefoxOptions() firefox_binaries = [ r"C:\Program Files\Mozilla Firefox\firefox.exe", r"C:\Program Files (x86)\Mozilla Firefox\firefox.exe", ] for fb in firefox_binaries: if os.path.isfile(fb): options.binary_location = fb q.put(f"使用Firefox浏览器: {fb}") break gecko_paths = [ os.path.join(os.path.expanduser("~"), ".wdm", "drivers", "geckodriver", "win64"), os.path.join(tempfile.gettempdir(), "router_tool_wdm"), ] gecko_found = None for p in gecko_paths: if os.path.isdir(p): for f in os.listdir(p): if "geckodriver" in f.lower() and f.endswith(".exe"): gecko_found = os.path.join(p, f) break if gecko_found: break if gecko_found: q.put(f"找到Firefox驱动: {gecko_found}") service = FirefoxService(executable_path=gecko_found) driver = webdriver.Firefox(service=service, options=options) else: driver = webdriver.Firefox(options=options) else: edge_driver_paths = [ r"C:\Program Files (x86)\Microsoft\Edge\Application\msedgedriver.exe", r"C:\Program Files\Microsoft\Edge\Application\msedgedriver.exe", os.path.join(os.path.expanduser("~"), ".wdm", "drivers", "edgedriver", "win64"), os.path.join(tempfile.gettempdir(), "router_tool_wdm"), ] found = None for p in edge_driver_paths: if os.path.isdir(p): for f in os.listdir(p): if f.endswith("msedgedriver.exe"): found = os.path.join(p, f) break if found: break elif os.path.isfile(p): found = p; break if found: q.put(f"找到Edge驱动: {found}") driver = webdriver.Edge(found) else: driver = webdriver.Edge() q.put("浏览器启动成功") except Exception as e2: q.put(f"所有方式均失败: {str(e2)}") raise driver.implicitly_wait(10) q.put("隐式等待已设置") q.put("正在识别设备类型") device_type = get_device_type(driver, q) q.put("识别完成.") q.put("准备登录...") login(driver, username, password, q, device_type) q.put("登录操作完成") q.put("准备获取PON信息...") get_pon_info(driver, q) q.put("获取PON信息完成") q.put("设置wifi启用状态") set_wifi_state(driver, q, wifi_state) q.put("设置wifi启用状态完毕") q.put("准备设置WIFI名称和密码...") set_wifi_name_and_password(driver, q, wifi_name, wifi_password, update_wifi_name, update_wifi_password) q.put("设置WIFI名称密码成功") q.put("准备设置自动重启...") set_reboot(driver, q) q.put("设置自动重启完成") q.put("准备注册LOID...") register_loid(driver, code, q) q.put("注册LOID完成") q.put("所有操作完成!") except Exception as e: import traceback q.put(f"运行异常: {str(e)}") q.put(f"异常详情: {traceback.format_exc()}") finally: q.put("浏览器将在一分钟后关闭...") time.sleep(60) if driver: driver.quit() driver = None q.put("浏览器已关闭") def update_ui(): nonlocal start_button try: while True: message = q.get_nowait() add_log(log_text, message) if "登录成功" in message: status_label.config(text="状态: 登录成功", foreground="green") elif "失败" in message: status_label.config(text="状态: 操作失败", foreground="red") elif "浏览器已关闭" in message: status_label.config(text="状态: 全部完成", foreground="blue") start_button.config(state=tk.NORMAL) return except queue.Empty: pass log_text.after(100, update_ui) start_button.config(state=tk.DISABLED) status_label.config(text="状态: 运行中", foreground="orange") thread = threading.Thread(target=worker) thread.daemon = True thread.start() update_ui() def on_closing(root, log_text): global driver add_log(log_text, "正在关闭程序...") if driver: add_log(log_text, "正在关闭浏览器...") driver.quit() driver = None root.destroy() def main(): root = tk.Tk() root.title("路由器管理工具") root.geometry("700x600") root.resizable(True, True) main_frame = ttk.Frame(root, padding="20") main_frame.pack(fill=tk.BOTH, expand=True) main_frame.grid_columnconfigure(1, weight=1) main_frame.grid_rowconfigure(13, weight=1) ttk.Label(main_frame, text="账号:", font=("微软雅黑", 12)).grid(row=0, column=0, sticky=tk.W, pady=10) username_var = tk.StringVar(value="") username_entry = ttk.Entry(main_frame, textvariable=username_var, font=("微软雅黑", 12)) username_entry.grid(row=0, column=1, pady=10, sticky=tk.EW) ttk.Label(main_frame, text="密码:", font=("微软雅黑", 12)).grid(row=1, column=0, sticky=tk.W, pady=10) password_var = tk.StringVar(value="") password_entry = ttk.Entry(main_frame, textvariable=password_var, font=("微软雅黑", 12), show="*") password_entry.grid(row=1, column=1, pady=10, sticky=tk.EW) is_admin_mode = tk.BooleanVar(value=False) def toggle_admin_mode(): if is_admin_mode.get(): username_var.set("") password_var.set("") username_entry.config(state=tk.NORMAL) password_entry.config(state=tk.NORMAL) admin_button.config(text="选择超级管理员账号") is_admin_mode.set(False) else: username_var.set("CMCCAdmin") password_var.set("aDm8H%MdA") username_entry.config(state=tk.DISABLED) password_entry.config(state=tk.DISABLED) admin_button.config(text="切换为普通账号") is_admin_mode.set(True) admin_button = ttk.Button(main_frame, text="选择超级管理员账号", command=toggle_admin_mode) admin_button.grid(row=0, column=2, pady=10, padx=5) def toggle_password(): if password_entry.cget("show") == "*": password_entry.config(show="") password_toggle.config(text="隐藏") else: password_entry.config(show="*") password_toggle.config(text="显示") password_toggle = ttk.Button(main_frame, text="显示", command=toggle_password) password_toggle.grid(row=1, column=2, pady=10, padx=5) ttk.Label(main_frame, text="LOID码:", font=("微软雅黑", 12)).grid(row=2, column=0, sticky=tk.W, pady=10) code_var = tk.StringVar(value="11111111") code_entry = ttk.Entry(main_frame, textvariable=code_var, font=("微软雅黑", 12)) code_entry.grid(row=2, column=1, pady=10, sticky=tk.EW) update_wifi_name_var = tk.BooleanVar(value=False) def on_update_wifi_name_change(*args): if update_wifi_name_var.get(): wifi_name_entry.config(state=tk.NORMAL) else: wifi_name_entry.config(state=tk.DISABLED) update_wifi_name_checkbox = ttk.Checkbutton(main_frame, text="修改WiFi名称", variable=update_wifi_name_var, command=on_update_wifi_name_change) update_wifi_name_checkbox.grid(row=3, column=0, columnspan=2, pady=5, sticky=tk.W) ttk.Label(main_frame, text="WiFi名称:", font=("微软雅黑", 12)).grid(row=4, column=0, sticky=tk.W, pady=10) wifi_name_var = tk.StringVar(value="") wifi_name_entry = ttk.Entry(main_frame, textvariable=wifi_name_var, font=("微软雅黑", 12), state=tk.DISABLED) wifi_name_entry.grid(row=4, column=1, pady=10, sticky=tk.EW) update_wifi_password_var = tk.BooleanVar(value=False) def on_update_wifi_password_change(*args): if update_wifi_password_var.get(): wifi_password_entry.config(state=tk.NORMAL) wifi_password_toggle.config(state=tk.NORMAL) else: wifi_password_entry.config(state=tk.DISABLED) wifi_password_toggle.config(state=tk.DISABLED) update_wifi_password_checkbox = ttk.Checkbutton(main_frame, text="修改WiFi密码", variable=update_wifi_password_var, command=on_update_wifi_password_change) update_wifi_password_checkbox.grid(row=5, column=0, columnspan=2, pady=5, sticky=tk.W) ttk.Label(main_frame, text="WiFi密码:", font=("微软雅黑", 12)).grid(row=6, column=0, sticky=tk.W, pady=10) wifi_password_var = tk.StringVar(value="") wifi_password_entry = ttk.Entry(main_frame, textvariable=wifi_password_var, font=("微软雅黑", 12), show="*", state=tk.DISABLED) wifi_password_entry.grid(row=6, column=1, pady=10, sticky=tk.EW) def toggle_wifi_password(): if wifi_password_entry.cget("show") == "*": wifi_password_entry.config(show="") wifi_password_toggle.config(text="隐藏") else: wifi_password_entry.config(show="*") wifi_password_toggle.config(text="显示") wifi_password_toggle = ttk.Button(main_frame, text="显示", command=toggle_wifi_password, state=tk.DISABLED) wifi_password_toggle.grid(row=6, column=2, pady=10, padx=5) wifi_state_var = tk.BooleanVar(value=True) wifi_state_checkbox = ttk.Checkbutton(main_frame, text="启用WiFi", variable=wifi_state_var) wifi_state_checkbox.grid(row=7, column=0, columnspan=2, pady=10, sticky=tk.W) ttk.Label(main_frame, text="浏览器:", font=("微软雅黑", 12)).grid(row=9, column=0, sticky=tk.W, pady=10) browser_var = tk.StringVar(value="Edge") browser_frame = ttk.Frame(main_frame) browser_frame.grid(row=9, column=1, pady=10, sticky=tk.W) ttk.Radiobutton(browser_frame, text="Edge", variable=browser_var, value="Edge").pack(side=tk.LEFT, padx=(0, 15)) ttk.Radiobutton(browser_frame, text="Chrome", variable=browser_var, value="Chrome").pack(side=tk.LEFT, padx=(0, 15)) ttk.Radiobutton(browser_frame, text="Firefox", variable=browser_var, value="Firefox").pack(side=tk.LEFT) status_label = ttk.Label(main_frame, text="状态: 就绪", font=("微软雅黑", 10), foreground="green") status_label.grid(row=10, column=0, columnspan=2, pady=5) start_button = ttk.Button(main_frame, text="开始执行", command=lambda: run_automation( username_var.get(), password_var.get(), code_var.get(), wifi_state_var.get(), wifi_name_var.get(), wifi_password_var.get(), update_wifi_name_var.get(), update_wifi_password_var.get(), browser_var.get(), log_text, status_label, start_button )) start_button.grid(row=11, column=0, columnspan=2, pady=10) ttk.Label(main_frame, text="实时日志:", font=("微软雅黑", 10)).grid(row=12, column=0, columnspan=3, sticky=tk.W) log_text = scrolledtext.ScrolledText(main_frame, font=("Consolas", 10)) log_text.grid(row=13, column=0, columnspan=3, pady=5, sticky=tk.NSEW) root.protocol("WM_DELETE_WINDOW", lambda: on_closing(root, log_text)) root.mainloop() if __name__ == '__main__': main()