如果失败需要重新运行代码,有没有?

Need to run the code again if it fails, is there anyway out?

我写了一个 selenium 自动化代码,但是由于 Salesforce 网站,它非常不稳定, 我的代码需要一些专业知识。 我想知道如果代码失败,我如何重新 运行 代码。 下面是我的代码, 我将无法分享我的部分代码。 我正在尝试使用 for 循环,但是我无法正确使用它, 我什至尝试了 while 循环,但我不知道它是如何工作的。

from selenium import webdriver
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from datetime import date
from datetime import timedelta
import pandas as pd
#rom glob import glob
from pathlib import Path
import pyodbc
import sqlalchemy
from urllib.parse import quote_plus
import win32com.client as win32
import warnings
warnings. filterwarnings("ignore")
#import sqlalchemy as sa

# PRE REQUSIT
today = date.today()
yesterday = today - timedelta(days = 1)
yesterday1 = yesterday.strftime('%d/%m/%Y')
yesterday2 = yesterday.strftime('%d%m%y')
loginfmt= 'q'4sag 
#passward= 'av erg'
passward= 'wergwn'
search= 'ws'ergwerg
sql_userid='asdadsgfsdg'
sql_pwd= 'z5xv154fxgv'

fp = webdriver.FirefoxProfile()
fp.set_preference('browser.download.folderList', 2)
fp.set_preference('browser.download.manager.showWhenStarting', False)
fp.set_preference('browser.download.dir', r"\abc\bcd\adff\asfg\python basics\web scraping\salceforce code\salesforcecode3downloads")
fp.set_preference('browser.helperApps.neverAsk.openFile', 'text/csv,application/x-msexcel,application/excel,application/x-excel,application/vnd.ms-excel,image/png,image/jpeg,text/html,text/plain,application/msword,application/xml,application/xls,application/csv')
fp.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv,application/x-msexcel,application/excel,application/x-excel,application/vnd.ms-excel,image/png,image/jpeg,text/html,text/plain,application/msword,application/xml,application/xls,application/csv')
fp.set_preference('browser.helperApps.alwaysAsk.force', False)
fp.set_preference('browser.download.manager.alertOnEXEOpen', False)
fp.set_preference('browser.download.manager.focusWhenStarting', False)
fp.set_preference('browser.download.manager.useWindow', False)
fp.set_preference('browser.download.manager.showAlertOnComplete', False)
fp.set_preference('browser.download.manager.closeWhenDone', False)
fp.set_preference("dom.forms.number", False)
fp.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv,application/x-msexcel,application/excel,application/x-excel,application/vnd.ms-excel,image/png,image/jpeg,text/html,text/plain,application/msword,application/xml,application/xls,application/csv,,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')

html_body2='<div>Hi Team,<br/> File saved to path:- <a href= "\\\abc\bcd\adff\asfg\dashboard">"[0o0]" </a> <br>  File uploaded successfully <br><br></div><div> Thanks & Regards,.<br> BIA Team </div>'

html_body3='<div>Hi Team,<br/> Automation failed please upload the file manually.<br><br></div><div> Thanks & Regards,.<br> BIA Team </div>'



to = ('bfdds'';''safsdg')

def file_s():
    outlook = win32.Dispatch('outlook.application')
    mail = outlook.CreateItem(0)
    mail.To =  to
    mail.CC = 'abc'
    mail.Subject = 'Good will Automation successfull'
    mail.Body = 'Message body'
    mail.HTMLBody = html_body2 #this field is optional

    # To attach a file to the email (optional):
    #attachment  = "Path to the attachment"
    #mail.Attachments.Add(attachment)

    mail.Send()

def file_f():
    outlook = win32.Dispatch('outlook.application')
    mail = outlook.CreateItem(0)
    mail.To =  to
    mail.CC = 'abc'
    mail.Subject = 'Good will Automation Failed'
    mail.Body = 'Message body'
    mail.HTMLBody = html_body3 #this field is optional

    # To attach a file to the email (optional):
    #attachment  = "Path to the attachment"
    #mail.Attachments.Add(attachment)

    mail.Send()


try:
    
    browser = webdriver.Firefox(executable_path =(r"\abc\bcd\adff\asfg\Desktop\python basics\geckodriver.exe"),firefox_profile=fp,service_log_path=r'\abc\bcd\adff\asfg\python basics\web scraping\salceforce code\geckodriver.log')
    #browser = webdriver.Chrome(executable_path =(r"\abc\bcd\adff\asfg\Desktop\python basics\chromedriver.exe"))
    #browser = webdriver.Edge(executable_path=(r"\abc\bcd\adff\asfg\Desktop\python basics\msedgedriver.exe"))
    website_URL ="https://h3g.my.salesforce.com"
    browser.get(website_URL)
    
    # ACTUAL CODE
    WebDriverWait(browser, 30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="i0116"]'))).send_keys(loginfmt)
    browser.find_element_by_xpath('//*[@id="idSIButton9"]').click()
    WebDriverWait(browser, 30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="passwordInput"]'))).send_keys(passward)
    browser.find_element_by_xpath('//*[@id="submitButton"]').click()
    #WebDriverWait(browser, 5, poll_frequency=2).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="idBtn_Back"]'))).click()
    #time.sleep(10)
    WebDriverWait(browser,30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'//*[@id="idBtn_Back"]'))).click()
    #browser.find_element_by_xpath('//*[@id="idBtn_Back"]').click()
    time.sleep(20)
    
    browser.find_element_by_xpath("/html/body/div[2]/div[2]/div/button").click()
    
    goodwill= 'Goodwill Credit Report'
    
    
    browser.find_element_by_xpath('//*[@class="slds-input"]').send_keys(goodwill)
    time.sleep(5)
    browser.find_element_by_xpath("/html/body/div[4]div[1]/div/div[2]/div[1]/div/search_dialog-instant-results-list/div/search_dialog-instant-result-item[1]/div[1]/div[2]/span").click()
    
    time.sleep(7)
    iframe3=browser.find_element_by_xpath("//iframe[@title=\'Report Viewer\']") #(//iframe[@title='Report Viewer'])[2] 
    browser.switch_to.frame(iframe3)
    #//iframe[@title=\'Report Viewer\']
    time.sleep(240)
    browser.find_element_by_xpath("/html/body/div[9]/div[1]/div[1]/div[2]/div/div/div/div[3]/div/div/button").click()
    
    
    #WebDriverWait(browser,30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[9]/div/div[1]/div/div[1]/div[2]/div/div/div/div/div/div/div[1]/div/div[2]/div/div[2]/ul/li[2]/div/div/div/div/div/div/button/span[3]'))).click()
    #browser.find_element_by_xpath("/html/body/div[9]/div/div[1]/div/div[1]/div[2]/div/div/div/div/div/div/div[1]/div/div/div[2]/div/div[2]/ul/li[2]/div/div/div/div/div/div/button/span[3]").click()
    #browser.find_element(By.XPATH,'/html/body/div[9]/div/div[1]/div/div[1]/div[2]/div/div/div/div/div/div/div[1]/div/div/div/div[2]/ul/li[2]/div/div/div/div/div/div/button/span[3]').click()
    
    fnd_ele = browser.find_element(By.XPATH, '/html/body/div[9]/div/div[1]/div/div[1]/div/div/div[3]/div/div/div/div/div/div/div[2]/div/div[2]/ul/li[2]/div/div/div/div/div/div/button/span[3]')
    fnd_ele.click()
    
    WebDriverWait(browser,30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'/html/bodydiv/div/div[2]/div/div/span/a'))).click()
    #browser.find_element_by_xpath("/html/body/span/section/div/div/span/a").click()
    
    WebDriverWait(browser,30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'//*[@class="slds-input"]'))).send_keys(yesterday1)
    #browser.find_element_by_xpath('//*[@class="slds-input"]').send_keys(yesterday1)
    
    #time.sleep(5)
    WebDriverWait(browser,30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'//div[@class = "filter-date-picker slds-form-element slds-m-to_none"]/div/div/div/div/input[@class="slds-input"]'))).send_keys(yesterday1)
    #browser.find_element_by_xpath('//div[@class = "filter-date-picker slds-form-element slds-m-to_none"]/div/div/input[@class="slds-input"]').send_keys(yesterday1)
    
    #time.sleep(3)
    WebDriverWait(browser,30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'/html/body/spandiv/footer/div[2]/button[2]'))).click()
    #browser.find_element_by_xpath('/html/bodydiv/div/footer/div[2]/button[2]').click()
    
    
    WebDriverWait(browser,30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[1]/div/div[1]/div[1]/div[1]/div[2]/div/div/div/div[5]/div/div/button'))).click()
    #browser.find_element_by_xpath('/html/body/div[9]/div[1]/div[1]/div[1]/div[2]/div/div/div/div[5]/div/div/button').click()
    
    #time.sleep(20)
    WebDriverWait(browser,30, poll_frequency=5).until(EC.element_to_be_clickable((By.XPATH,'/htmldiv/ul/li[3]/a'))).click()
    #browser.find_element_by_xpath('/html/body/span/div/ul/li[3]/a').click()
    
    
    main_window_handle = browser.current_window_handle
    print("Current window",main_window_handle)
    browser.switch_to.default_content()
    
    WebDriverWait(browser,10, poll_frequency=5).until(EC.visibility_of_element_located((By.XPATH,'/html/body/div[2]/div/div[2]/div/div[3]/buton[2]/span'))).click()
    
    time.sleep(10)
    #WebDriverWait(browser,10, poll_frequency=5).until(EC.visibility_of_element_located((By.XPATH,'/html/body/div[4]/div[1]/section/div[1]/div/div[1]/div[2]/div/div/ul[2]/li[2]/div[2]/buton/lightning-primitive-icon'))).click()
    browser.find_element_by_xpath("/html/body/div[4]/div[1]/section/div[1]/div/div[1]/div[2]/div/div/ul[2]/li[2]/div[2]/buttn/lightning-primitive-icon").click()
    
    time.sleep(20)
    browser.quit()
    
    
    " EDITING THE FILE "
    
    def get_latest_file(src_path,extension,method='st_mtime'):
        """ 
        Takes in a raw path and extension to parse over
        returns a single file with the last modified date
    
        methods:
        st_mtime: It represents the time of most recent content modification. It is 
        expressed in seconds.
        st_ctime: It represents the time of most recent metadata change on Unix 
        and creation time on Windows. It is expressed in seconds.
        """
    
        extension = extension if extension[0] != '.' else extension[1:]
    
        files = (Path(src_path).glob(f'*.{extension}'))
    
        if method == 'st_mtime':
            file_dictionary = {file : file.stat().st_mtime for file in files}
        elif method == 'st_ctime':
            file_dictionary = {file : file.stat().st_ctime for file in files}
        else:
            raise Exception(f'{method} not valid for this function')
    
        max_file = max(file_dictionary, key=file_dictionary.get)
    
    
        return max_file
    
    latest = get_latest_file(r'C:\abc\bcd\adff\asfg\python basics\web scraping\salceforce code\salesforcecode3downloads',extension='xlsx',method='st_mtime')
    print(latest)
    df = pd.read_excel(latest)
    
    #df= pd.read_excel("Complaints-2022-03-09-07-52-48.xlsx")
    df.drop([0,1,2,3,4,5,6,7],inplace=True)
    df.columns = df.iloc[0] 
    df.reset_index(drop=True, inplace=True)
    df2=df.iloc[1:]
    df3=df2.iloc[:,1:]
    df3.drop(df3.tail(1).index,inplace=True)
    df4=df3.drop(df3.columns[1], axis=1)
    
    df4.to_csv(r'\abc\bcd\adff\asfg\Goodwill Credit Report-'+yesterday2+'.csv', header=True, index=False,)
    df4.to_csv(r'\abc\bcd\adff\asfg\Goodwill Credit Report-'+yesterday2+'.csv', header=True, index=False,)
    print("Excel file edited")
    #df3.columns
    
    df5 =  df4.drop(['Dispute Id: Case Number','Date','Status','Installment Amount','Total Installments','Service Terms','Service Amount','Service End Date','Mode',
    'Notes'], axis = 1)
    
    
    conn = pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};'
    r'SERVER=something;'
    r'DATABASE=something;'
    r'Uid='+sql_userid+';'
    r'Pwd='+sql_pwd+';')
    cursor = conn.cursor()
    cursor.execute('Truncate table somethingTemp')
    conn.commit()
    cursor.close()
    conn.close()
    print("file truncate succesfull")
    
    driver='SQL Server Native Client 11.0'
    params = quote_plus(r'DRIVER={SQL Server Native Client 11.0};'
    r'SERVER=something;'
    r'DATABASE=something;'
    r'Uid='+sql_userid+';'
    r'Pwd='+sql_pwd+';')
    engine = sqlalchemy.create_engine('mssql+pyodbc:///?odbc_connect=%s' % params)
    
    # converting the created date column to str then changing it to date time and formating it dd-mm-yy
    df5['Created Date']=df5['Created Date'].astype(str)
    df5['Created Date']=pd.to_datetime(df5['Created Date'], format="%d/%m/%Y")
    
    df5.to_sql('C_VisionPay_Temp', con = engine, if_exists = 'append', index = False)
    
    
    df5['Created Date']
    conn = pyodbc.connect(r'DRIVER={SQL Server Native Client 11.0};'
    r'SERVER=something;'
    r'DATABASE=something;'
    r'Uid='+sql_userid+';'
    r'Pwd='+sql_pwd+';')
    cursor = conn.cursor()
    params=date(yesterday.year,yesterday.month,yesterday.day)
    storedProc = "something"
    cursor.execute( storedProc, params )
    conn.commit()
    cursor.close()
    conn.close()
    print("file executed sucessfully " )
    
    file_s()
    
except:
    file_f()

这里有很多睡眠,这是 tell-tale 自动化代码编写不当的标志。这将使自动化暴露于您所描述的不需要的故障。

我们使用睡眠而不是更合适的显式或流畅等待有什么原因吗?

我个人建议不要尝试重新运行失败的自动化测试直到它们通过,那是一个听起来很乱的兔子洞。相反,我会专注于使代码不眠不休且健壮。关于为什么使用睡眠不是一个好主意,有大量信息。

如果可以的话,还有一些观察:

  1. 应该避免像 /html/body/div[9]/div[1]/div[1]/div[2]/div/div/div/div[3]/div/div/button 这样的 Xpaths,这些很容易改变并且会增加代码的脆弱性

  2. 有一些示例,其中 id 由代理通过 xpath 处理,例如:browser.find_element_by_xpath('//*[@id="idSIButton9"]').click()。我们最好去掉中间人,直接通过 id 查找元素。例如:browser.find_element_by_id('idSIButton9').click

  3. 有很多重复的代码,如果一个小东西发生变化,我们可能需要做很多修改来修正它。理想情况下,我们只想在一个地方进行更改

祝一切顺利