You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:45:40