Python企业网站密码修改程序:循环重复与邮件发送异常问题
问题描述
我正在开发一款用于修改公司内部网站用户密码的Python程序,目前遇到两个核心问题:
- 半数账号已切换为邮箱登录而非用户名登录,这类账号需通过邮箱修改密码,但程序无法触发该类账号的邮件发送流程。
- 循环执行完成后会出现重复运行的情况。
程序通过Try/While循环检测账号是否已切换登录方式,或管理员账号是否成功完成密码修改。以下是相关实现代码:
代码实现
1. 密码修改主程序(PassChngWeb.py)
import time from hashlib import new from multiprocessing.connection import wait from select import select from tkinter import E from webbrowser import BaseBrowser, Chrome from xml.etree.ElementPath import find from xmlrpc.client import boolean import win32clipboard import win32com.client as win32 from selenium import webdriver from selenium.common.exceptions import NoSuchElementException, TimeoutException from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.select import Select from selenium.webdriver.support.ui import WebDriverWait import ADconnect def ChangeLogin(AdminUser, AdminPassword): options = webdriver.ChromeOptions() options.add_experimental_option('excludeSwitches', ['enable-logging']) driver = webdriver.Chrome(options=options) driver.maximize_window() driver.get('https://power.dat.com') def LoginPass(): Logon = driver.find_element(By.XPATH, '//*[@id="mat-input-1"]') Logon.send_keys(AdminUser) password = driver.find_element(By.XPATH, '//*[@id="mat-input-0"]') password.send_keys(AdminPassword) loginbutton = driver.find_element(By.XPATH, '//*[@id="submit-button"]') loginbutton.click() time.sleep(3) LoginPass() def AdminBtn(): AD = "https://power.dat.com/admin/office" driver.execute_script("window.open(' ');") driver.switch_to.window(driver.window_handles[1]) driver.get(AD) AdminBtn() WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="search"]'))).send_keys(ADconnect.email) time.sleep(3) UsrPro = driver.find_element(By.XPATH, '//td[7]') UsrPro.click() #Password password = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='password']"))) password.clear() password.send_keys("totalyDude") #Confirm Password ConPass = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='confirmPassword']"))) ConPass.clear() ConPass.send_keys("totalyDude") #Copy Username UserName = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='loginId']"))) UserName.send_keys(Keys.CONTROL, 'a') UserName.send_keys(Keys.CONTROL, 'c') #Save Button SaveBTN= WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="data"]/div[3]/table/tbody/tr/td[1]/ng-form/div/button[2]'))) SaveBTN.click() driver.quit() def TstAcct(): options = webdriver.ChromeOptions() options.add_experimental_option('excludeSwitches', ['enable-logging']) driver1 = webdriver.Chrome (options=options) driver1.maximize_window() driver1.get('https://power.dat.com') #Calling Username in clipboard win32clipboard.OpenClipboard() NewUserName = win32clipboard.GetClipboardData() time.sleep(3) #Send username driver1.find_element(By.XPATH, '//*[@id="mat-input-1"]').send_keys(NewUserName) #Send Password driver1.find_element(By.XPATH, '//*[@id="mat-input-0"]').send_keys('total2') def TstAcct(): options = webdriver.ChromeOptions() options.add_experimental_option('excludeSwitches', ['enable-logging']) driver1 = webdriver.Chrome (options=options) driver1.maximize_window() driver1.get('https://power.dat.com') #Calling Username in clipboard win32clipboard.OpenClipboard() NewUserName = win32clipboard.GetClipboardData() time.sleep(3) #Send username driver1.find_element(By.XPATH, '//*[@id="mat-input-1"]').send_keys(NewUserName) #Send Password driver1.find_element(By.XPATH, '//*[@id="mat-input-0"]').send_keys('totalyDude') #Click Login # driver1.find_element(By.XPATH, '//*[@id="submit-button"]').click() #Get User name that is logged in # confirm = (WebDriverWait(driver1, 20).until(EC.visibility_of_element_located((By.XPATH, "//a[@id='user-salutation']"))).get_attribute("innerHTML")) # print(confirm) #Check Username Matches and send email if it does try: driver1.find_element(By.XPATH, '//*[@id="submit-button"]').click() while WebDriverWait(driver1, 20).until(EC.presence_of_element_located((By.XPATH, "//div[@class='error-content']"))): time.sleep(3) # WebDriverWait(driver1, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='error-content']"))).click() driver1.find_element(By.XPATH, "//a[@id='password-reset']").click() driver1.find_element(By.XPATH, "//span[normalize-space()='CONTINUE']").click() outlook1 = win32.Dispatch('outlook.application') mail = outlook1.CreateItem(0) mail.To = ADconnect.email mail.Subject = "DAT Account Password Change" mail.Body = (ADconnect.FirstN + " your DAT account has been transitioned over to email login. You should receive a email from DAT with a link to change your password. \n \n" + "Please see the log in info below:\n \n" "Username: " + ADconnect.email + "\nPassword: total2 \n\n" "You can log in with the below link \n" "https://power.dat.com") print("Email sent") break except: print("issue occurred") try: confirm = (WebDriverWait(driver1, 20).until(EC.visibility_of_element_located((By.XPATH, "//a[@id='user-salutation']"))).get_attribute("innerHTML")) while confirm == ("Hi " + NewUserName): print(confirm) print("Users password has been changed") outlook = win32.Dispatch('outlook.application') mail = outlook.CreateItem(0) mail.To = ADconnect.email mail.Subject = "DAT Account Password Change" mail.Body = (ADconnect.FirstN + " your DAT account password has been changed!\n \n" + "Please see the log in info below:\n \n" "Username: " + NewUserName + "\nPassword: total2 \n\n" "You can log in with the below link \n" "https://power.dat.com") mail.Send() break except: print("issue occurred") finally: driver1.quit() TstAcct()
2. 账号查询程序(AcctCheck.py)
import email from multiprocessing import connection from sqlite3 import Cursor, Row from tabnanny import check from types import NoneType import pyodbc import pandas as pd from psycopg2 import sql import ADconnect import PassChngWeb def chckAcct(): SQLEmail = ADconnect.email Hostname = 'ServerTime' IP_Address = '111.11.1.11' Driver_Name = 'SQL SERVER' Server_Name = "ServerTime" DATABASE_NAME = 'TimeToParty' connection_STRING = f""" DRIVER= {{{Driver_Name}}}; SERVER={Server_Name}; DATABASE={DATABASE_NAME}; Trust_Connection=yes; """ conn = pyodbc.connect(connection_STRING) print(conn) cursor = conn.cursor() check = cursor.execute("SELECT Account_Number FROM DATacctTQLfin WHERE Email_Address = ?", (SQLEmail,) ) while check is None: import WebDAT print("No user account found") WebDAT.CreateAcct() WebDAT.sqlInsert() break else: for x in cursor.fetchone(): var = x print(var) check = cursor.fetchone() global AdminUser global AdminPassword if check is None: import WebDAT print("No user account found") AdminUser = '0' AdminPassword = '0' WebDAT.CreateAcct() for x in check: var = x print(var) if x == ('jsparky'): print("Username: JSparky") AdminUser = "jsparky" AdminPassword = "IMaLostBoy" PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("JSparky2/"): print(x) print("Username: JSparky2") AdminUser = "JSparky2" AdminPassword = "StillALostBoy" PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("jazzadmin"): print(x) print("Username: jazzadmin") AdminUser = "jazzadmin" AdminPassword = ("JazzHands") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("adminMean"): print(x) print("Username: adminMean") AdminUser = "adminMean" AdminPassword = ("TooTheFloor") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("RogerDat"): print(x) print("Username: RogerDat") AdminUser = "RogerDat" AdminPassword = ("ToTheWall") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("LukeSkyWalker"): print(x) print("Username: LukeSkyWalker") AdminUser = "LukeSkyWalker" AdminPassword = ("TillTheSweat") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("SuperKlein"): print(x) print("Username: SuperKlein") AdminUser = "SuperKlein" AdminPassword = ("DropsDownMy") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("NoDetention/"): print(x) print("Username: NoDetention") AdminUser = "NoDetention" AdminPassword = ("Ballzzzz") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("Vader"): print(x) print("Username: Vader") AdminUser = "Vader" AdminPassword = ("IamYouFather") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("R2D2/"): print(x) print("Username: R2D2") AdminUser = "R2D2" AdminPassword = ("R2D2") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) if x == ("BabyYoda"): print(x) print("Username: BabyYoda") AdminUser = "BabyYoda" AdminPassword = ("FalconX") PassChngWeb.ChangeLogin(AdminUser, AdminPassword) cursor.close() conn.close()
问题解决方案
1. 邮箱登录账号邮件发送失败修复
问题根源
TstAcct()函数被重复定义,第一个未完成的定义被第二个覆盖,导致逻辑混乱。- 错误检测的While循环依赖
WebDriverWait的强制等待,若错误元素不存在会直接抛出异常进入except分支,无法执行邮件发送。 - 剪贴板操作未关闭,可能导致后续读取异常或资源泄漏。
修改后代码
def TstAcct(): options = webdriver.ChromeOptions() options.add_experimental_option('excludeSwitches', ['enable-logging']) driver1 = webdriver.Chrome(options=options) driver1.maximize_window() driver1.get('https://power.dat.com') # 安全读取剪贴板并关闭 win32clipboard.OpenClipboard() try: NewUserName = win32clipboard.GetClipboardData() finally: win32clipboard.CloseClipboard() time.sleep(3) # 输入登录信息 driver1.find_element(By.XPATH, '//*[@id="mat-input-1"]').send_keys(NewUserName) driver1.find_element(By.XPATH, '//*[@id="mat-input-0"]').send_keys('totalyDude') try: driver1.find_element(By.XPATH, '//*[@id="submit-button"]').click() # 检测登录成功的欢迎信息 confirm = WebDriverWait(driver1, 10).until(EC.visibility_of_element_located((By.XPATH, "//a[@id='user-salutation']"))).get_attribute("innerHTML") if confirm == f"Hi {NewUserName}": print(confirm) print("用户密码已修改") # 发送密码修改成功邮件 outlook = win32.Dispatch('outlook.application') mail = outlook.CreateItem(0) mail.To = ADconnect.email mail.Subject = "DAT账号密码修改通知" mail.Body = (f"{ADconnect.FirstN} 你的DAT账号密码已修改!\n\n" "登录信息如下:\n\n" f"用户名: {NewUserName}\n密码: total2 \n\n" "登录链接:https://power.dat.com") mail.Send() except TimeoutException: # 登录失败,判断是否为邮箱登录账号 try: # 检测错误提示元素 WebDriverWait(driver1, 5).until(EC.presence_of_element_located((By.XPATH, "//div[@class='error-content']"))) # 触发密码重置流程 driver1.find_element(By.XPATH, "//a[@id='password-reset']").click() driver1.find_element(By.XPATH, "//span[normalize-space()='CONTINUE']").click() # 发送邮箱登录通知邮件 outlook1 = win32.Dispatch('outlook.application') mail = outlook1.CreateItem(0) mail.To = ADconnect.email mail.Subject = "DAT账号切换为邮箱登录通知" mail.Body = (f"{ADconnect.FirstN} 你的DAT账号已切换为邮箱登录。你将收到DAT官方发送的密码重置链接。\n\n" "临时登录信息(若需):\n\n" f"用户名: {ADconnect.email}\n密码: total2 \n\n" "登录链接:https://power.dat.com") mail.Send() print("邮箱登录通知已发送") except Exception as e: print(f"检测登录状态时出现异常: {str(e)}") finally: driver1.quit()
2. 循环重复运行问题修复
问题根源
cursor.execute()返回游标对象,永远不为None,导致while check is None逻辑完全失效。- 重复调用
cursor.fetchone()导致游标移动,获取到错误的账号数据。 - 多个独立
if判断账号,若匹配多个条件会重复调用ChangeLogin()。
修改后代码
def chckAcct(): SQLEmail = ADconnect.email Hostname = 'ServerTime' IP_Address = '111.11.1.11' Driver_Name = 'SQL SERVER' Server_Name = "ServerTime" DATABASE_NAME = 'TimeToParty' connection_STRING = f""" DRIVER= {{{Driver_Name}}}; SERVER={Server_Name
相关产品推荐
相关产品推荐

