【Python Selenium】簡單數據生成腳本

最近因工做須要,寫了一個簡單的自動化腳本,純屬學習,順便學習下selenium模塊。css

廢話很少說,直接上代碼!!html

這裏一位大神重寫了元素定位、send_keys等方法,我們直接進行調用。web

適用Python3.6算法

  1 # coding=utf-8
  2 
  3 """
  4 basePageUtil.py
  5 基礎類basePage,封裝全部頁面都公用的方法,
  6 定義open函數,重定義find_element,switch_frame,send_keys等函數。
  7 在初始化方法中定義驅動driver,url,pagetitle
  8 """
  9 
 10 from selenium.webdriver.support.wait import WebDriverWait
 11 from selenium.webdriver.support import expected_conditions as EC
 12 from selenium.webdriver import ActionChains
 13 
 14 
 15 class basePage(object):
 16     """
 17     basePage封裝全部頁面都公用的方法,例如driver, url ,FindElement等
 18     """
 19     # 初始化driver,url,pagetitle等
 20     # 實例化basePage類時,最早執行的就是__init__方法,該方法的入參,其實就是basePage類的入參。
 21     #__init__方法不能有返回值,只能返回None
 22     # self只實例自己,相較於類Page而言。
 23 
 24     def __init__(self, selenium_driver, url, pagetitle='',downloadir='',pageurl=''):
 25         self.driver = selenium_driver
 26         self.url = url
 27         self.pagetitle = pagetitle
 28         self.downloadir = downloadir
 29         self.pageurl=pageurl
 30 
 31     # 經過title斷言進入的頁面是否正確。
 32     # 使用title獲取當前窗口title,檢查輸入的title是否在當前title中,返回比較結果(True 或 False)
 33     def on_page(self, pagetitle):
 34         return pagetitle in self.driver.title
 35 
 36     # 打開頁面,並校驗頁面連接是否加載正確
 37     # 以單下劃線_開頭的方法,在使用import *時,該方法不會被導入,保證該方法爲類私有的。
 38     def _open(self, url, pagetitle='',pageurl=''):
 39         # 使用get打開訪問連接地址
 40         self.driver.get(url)
 41         self.driver.maximize_window()
 42         print(self.driver.title,self.driver.current_url)
 43         if pagetitle:
 44             # 使用assert進行校驗,打開的窗口title是否與配置的title一致。調用on_page()方法
 45             assert self.on_page(pagetitle), "Check Page Error:\t%s" % url
 46         if pageurl:
 47             # 校驗打開後的url與傳入url是否一致
 48             assert pageurl==self.driver.current_url,'{0}!={1}'.format(pageurl,self.driver.current_url)
 49 
 50     # 定義open方法,調用_open()進行打開連接
 51     def open(self):
 52         self._open(self.url, self.pagetitle,self.pageurl)
 53 
 54     # 重寫元素定位方法
 55     def find_element(self, loc):
 56         try:
 57             # 等待元素可見
 58             return WebDriverWait(self.driver, 5).until(EC.visibility_of_element_located(loc))
 59         except Exception as e:
 60             elements = WebDriverWait(self.driver, 5).until(EC.visibility_of_any_elements_located(loc))
 61             return elements[0] if elements else False
 62 
 63     #重寫元素定位方法
 64     def find_elements(self, loc):
 65         try:
 66             # 等待元素可見
 67             return WebDriverWait(self.driver, 5).until(EC.visibility_of_any_elements_located(loc))
 68         except BaseException:
 69             print('page {0} does not have locator {1}'.format(self, loc))
 70 
 71     # 重寫switch_frame方法
 72     def switch_frame(self, loc):
 73         return self.driver.switch_to_frame(loc)
 74 
 75     # 重寫switch_frame方法
 76     def switch_window(self, loc):
 77         return self.driver.switch_to_window(loc)
 78 
 79     # 定義script方法,用於執行js腳本
 80     def script(self, src):
 81         self.driver.execute_script(src)
 82 
 83     # 重寫定義send_keys方法
 84     def send_keys(self, loc: object, vaule: object, clear_first: object = True, click_first: object = True) -> object:
 85         try:
 86             if click_first:
 87                 self.find_element(loc).click()
 88             if clear_first:
 89                 self.find_element(loc).clear()
 90 
 91             self.find_element(loc).send_keys(vaule)
 92         except AttributeError:
 93             print('%s page does not have "%s" locator' % (self, loc))
 94 
 95     # 重寫鼠標懸停方法
 96     def move_to_element(self, element='', loc=''):
 97         if loc:
 98             element = self.find_element(loc)
 99         elif not element:
100             assert False,'Not Found Element'
101         ActionChains(self.driver).move_to_element(element).perform()

本身寫的腳本以下,腳本有些簡單,沒有進行類的封裝:數據庫

"""
selenium驅動Firefox實現人工操做進行數據生成,輸出日誌到文本文件
"""
from basePageUtil import *
from selenium import webdriver
from selenium.webdriver.common.by import By
import xlrd
import re
import time
from datetime import datetime,timedelta
from selenium.webdriver.common.keys import Keys

#讀取Excel表格數據
def excle_table(file,table,colnameindex,file_log,fb,by_index=0):
    # 某一行數據
    colvalues = table.row_values(colnameindex)
    #定義一個空列表,用來存放Excel的每行數據
    # list = []
    #表頭數據
    row = table.row_values(0)
    if row:
        list = {}
        for i in range(len(colvalues)):
            if i ==10:
                try:
                    #格式化Excel表日期
                    excel_date = xlrd.xldate.xldate_as_datetime(colvalues[i], 0)
                    #日期格式化爲str類型
                    dt = datetime.strptime(str(excel_date), "%Y-%m-%d %H:%M:%S").strftime('%Y-%m-%d')
                    #將日期數據傳入到相應的表頭下
                    list[row[i]] = dt
                except Exception:
                    # e_bd = '第{0}條數據,初登日期格式錯誤'.format(colnameindex) + '\n'
                    # fb.write(e_bd)
                    continue
            elif i == 11 or i ==12:
                try:
                    # 格式化Excel表日期
                    excel_date = xlrd.xldate.xldate_as_datetime(colvalues[i], 0)
                    # 日期格式化爲datetime類型
                    dt = datetime.strptime(str(excel_date), "%Y-%m-%d %H:%M:%S").strftime("%Y-%m-%d %H:%M")
                    # 將日期數據傳入到相應的表頭下
                    list[row[i]] = dt
                except Exception:
                    # e_edate = '第{0}條數據,起保日期、終保日期格式錯誤'.format(colnameindex) + '\n'
                    # fb.write(e_edate)
                    continue
            else:
                list[row[i]] = colvalues[i]
    return list
def flag(year):
    if year % 400 == 0 or (year % 100 != 0 and year % 4 == 0):
        return True
    else:
        return False

def login():
    driver = webdriver.Firefox()
    url = 'http://172.20.xx.xx/xxxx/login.do'
    driver.get(url)
    driver.maximize_window()
    UserName = "username"
    PassWord = "password"

    RawData = basePage(driver, url)
    # 登陸
    RawData.find_element((By.ID, 'j_username')).send_keys(UserName)
    RawData.find_element((By.ID, 'j_password')).send_keys(PassWord)
    RawData.find_element((By.ID, 'login_ok')).click()
    # 點擊數據生成
    RawData.find_element((By.LINK_TEXT, '數據生成')).click()

    # 點擊商業險數據生成
    RawData.find_element((By.ID, 'main_treeDemo_34_9_span')).click()
    #數據文件路徑
    file = r"C:\Users\zg\Desktop\data.xlsx"
    # 打開excle文件
    data = xlrd.open_workbook(file)
    # 讀取第一個sheet頁
    table = data.sheet_by_index(0)
    # 行數
    nrows = table.nrows
    #錯誤日誌文件
    file_out = r'C:\Users\zg\Desktop\log.txt'
    DateNow = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    fb = open(file_out,'a')
    fb.write(DateNow + '\n')
    # 數據條數
    succ_num = 0
    fail_num = 0
    NUM = nrows
    for data_index in range(1,NUM):

        listdata = excle_table(file,table,data_index,file_out,fb)
        if (len(listdata) <= 0):
            assert 0, u'Excle數據異常'
        try:
            #省份選擇
            RawData.find_element((By.XPATH,'//a[@lookupgroup=\'cityLookup\']/i')).click()
            # RawData.find_element((By.LINK_TEXT, '河北')).click()
            province = listdata['省份']
            time.sleep(0.5)
            #js設置搜索框大小
            scri1 = "var doc = document.getElementById('city');doc.style.height='685px';"
            scri2 = "var doc = document.getElementsByTagName('div');" \
                    "for(var i=0;i < doc.length;i++){" \
                    " if (doc[i].className == 'dialog dialog-box'){" \
                    "doc[i].style.top='20px';}}"
            scri3 = "var doc = document.getElementsByTagName('div');" \
                    "for(var i=0;i < doc.length;i++){" \
                    " if (doc[i].className == 'dialogContent layoutBox unitBox'){" \
                    "doc[i].style.height='690px';}}"
            #執行js腳本
            driver.execute_script(scri1)
            driver.execute_script(scri2)
            driver.execute_script(scri3)
            try:
                RawData.find_element((By.LINK_TEXT,province)).click()
            except:
                e_pro = '第{0}條數據省份有誤,'.format(data_index)
                fb.write(e_pro)
                raise

            #公司名稱
            RawData.find_element((By.XPATH,'//a[@id=\'companySelect\']/i')).click()
            #獲取公司名稱
            company = re.search('[^a-zA-Z\s]+', listdata['須要生成哪家公司的數據']).group()
            try:
                # 輸入公司名稱
                RawData.find_element((By.ID, 'compname')).send_keys(company)
                #點擊檢索
                RawData.find_element((By.XPATH, "//button[text()='檢索']")).click()
                #點擊選擇
                RawData.find_element((By.LINK_TEXT, '選擇')).click()
            except:
                RawData.find_element((By.XPATH, '/html/body/div[12]/div[1]/div/div/a[1]/i')).click()
                e_ComCode = '第{0}條數據公司名稱有誤,'.format(data_index)
                fb.write(e_ComCode)
                raise
            try:
                #數據庫選擇
                RawData.find_element((By.XPATH,"//button[@data-id='commerAreaVsUrl']")).click()
                loc_db = "/html/body/div/div/ul/li/a/span[text()='{0} 聯調']".format(province)
                RawData.find_element((By.XPATH, loc_db)).click()
            except:
                e_db = '第{0}條數據數據庫名稱有誤,'.format(data_index)
                fb.write(e_db)
                raise

            try:
                #業務種類選擇
                RawData.find_element((By.XPATH,"//button[@data-id='biz_bjautotypes']")).click()
                YWZL = listdata['業務種類']
                RawData.find_element((By.XPATH, "/html/body/div[13]/div/ul/li/a/span[text()='" + YWZL + "']")).click()
            except:
                e_YWZL = '第{0}條數據業務種類有誤,'.format(data_index)
                fb.write(e_YWZL)
                raise
            # 日期
            # 起保日期
            eds = driver.find_elements_by_xpath("//input[@name='effectiveDate']")
            # 終保日期
            exds = driver.find_elements_by_xpath("//input[@name='expireDate']")
            # 簽單日期
            bds = driver.find_elements_by_xpath("//input[@name='billDate']")
            # 投保查詢日期
            qds = driver.find_elements_by_xpath("//input[@name='queryDate']")
            # 起保日期
            effdt_data = listdata['起保日期']
            # 終保日期
            exdt_data = listdata['終保日期']
            # 起保日期格式化
            effdt_data_tra = datetime.strptime(effdt_data, "%Y-%m-%d %H:%M")
            # 終保日期格式化
            exdt_data_tra = datetime.strptime(exdt_data, "%Y-%m-%d %H:%M")
            #業務種類列表
            YWZL1 = ['連續5年沒有發生賠款','連續4年沒有發生賠款','連續3年沒有發生賠款','連續2年沒有發生賠款','連續1年沒有發生賠款']
            years = re.search('\d', YWZL).group()
            #對業務種類進行判斷
            if YWZL in YWZL1:

                if flag(effdt_data_tra.year) == True and effdt_data_tra.month == 2 and effdt_data_tra.day == 29:
                    flagYear = True
                else:
                    flagYear = False
                for i in range(0, int(years)):
                    # 傳入日期前數據清空
                    eds[i].clear()
                    exds[i].clear()
                    bds[i].clear()
                    qds[i].clear()
                    # 起保日期年份
                    effdt_year = effdt_data_tra.year
                    #起保日期減一天
                    effdt_now = effdt_data_tra - timedelta(days=1)
                    # 傳入起保日期
                    eds[i].send_keys(str(effdt_data_tra.strftime("%Y-%m-%d %H:%M")))
                    # 傳入終保日期
                    exds[i].send_keys(str(exdt_data_tra.strftime("%Y-%m-%d %H:%M")))
                    # 傳入簽單日期
                    bds[i].send_keys(effdt_now.strftime("%Y-%m-%d"))
                    # 傳入投保查詢日期
                    qds[i].send_keys(effdt_now.strftime("%Y-%m-%d"))
                    # 終保日期
                    exdt_data_tra = effdt_data_tra
                    if flagYear == True:
                        if flag(effdt_year - 1) == True:
                            effdt_data_tra_str = "{0}-02-29 00:00".format(effdt_year - 1)
                        if flag(effdt_year - 1) == False:
                            effdt_data_tra_str = "{0}-02-28 00:00".format(effdt_year - 1)
                        effdt_data_tra = datetime.strptime(effdt_data_tra_str, "%Y-%m-%d %H:%M")
                    else:
                        if flag(effdt_year) == True and (
                                effdt_data_tra.month > 2 or effdt_data_tra.month == 2 and effdt_data_tra.day == 29):
                            # 起保日期減366天
                            effdt_data_tra = effdt_data_tra - timedelta(days=366)
                        elif flag(effdt_year) == False and flag(effdt_year - 1) == True and effdt_data_tra.month < 3:
                            # 起保日期減366天
                            effdt_data_tra = effdt_data_tra - timedelta(days=366)
                        else:
                            # 起保日期減365天
                            effdt_data_tra = effdt_data_tra - timedelta(days=365)
            else:
                # 結案時間
                CTs = RawData.find_elements((By.XPATH, "//input[@name='ClaimCloseTime']"))

                for i in range(0,int(years)):
                    #傳入日期前數據清空
                    eds[0].clear()
                    exds[0].clear()
                    bds[0].clear()
                    qds[0].clear()
                    CTs[i].clear()
                    # 起保日期年份
                    effdt_year = effdt_data_tra.year
                    # 起保日期減一天
                    effdt_now = effdt_data_tra - timedelta(days=1)
                    # 起保日期加一天,結案時間
                    CT_now = effdt_data_tra + timedelta(days=i+1)
                    # 傳入起保日期
                    eds[0].send_keys(str(effdt_data_tra))
                    # 傳入終保日期
                    exds[0].send_keys(str(exdt_data_tra))
                    # 傳入簽單日期
                    bds[0].send_keys(effdt_now.strftime("%Y-%m-%d"))
                    # 傳入投保查詢日期
                    qds[0].send_keys(effdt_now.strftime("%Y-%m-%d"))
                    # 傳入結案時間
                    CTs[i].send_keys(CT_now.strftime("%Y-%m-%d %H:%M"))
            #向上翻頁
            RawData.find_element((By.ID, 'bjautolayout_table_css')).send_keys(Keys.PAGE_UP)
            try:
                #號牌選擇
                RawData.find_element((By.XPATH,"//button[@data-id='autolicenseType']")).click()
                license = listdata['號牌種類'].strip()
                RawData.find_element((By.XPATH, "/html/body/div[14]/div/ul/li/a/span[text()='"+license+"']")).click()
            except:
                e_license = '第{0}條數據號牌種類有誤,'.format(data_index)
                fb.write(e_license)
                raise

            try:
                #車輛類型
                RawData.find_element((By.XPATH,"//button[@data-id='car_type']")).click()
                CLLX = listdata['車輛種類']
                RawData.find_element((By.XPATH, "/html/body/div[15]/div/ul/li/a/span[text()='"+ CLLX +"']")).click()
            except:
                e_CLLX = '第{0}條數據車輛類型有誤,'.format(data_index)
                fb.write(e_CLLX)
                raise

            try:
                #使用性質
                RawData.find_element((By.XPATH,"//button[@data-id='car_type2s']")).click()
                SYXZ = listdata['使用性質'].strip()
                RawData.find_element((By.XPATH, "/html/body/div[16]/div/ul/li/a/span[text()='"+ SYXZ +"']")).click()
            except:
                e_SYXZ = '第{0}條數據使用性質有誤,'.format(data_index)
                fb.write(e_SYXZ)
                raise

            #車主姓名
            # RawData.find_element((By.ID,"roleName")).send_keys('張三')

            #保額
            # RawData.find_element((By.ID,"sumLimit")).send_keys('1000')

            try:
                #車三項
                RawData.find_element((By.XPATH,"//button[@data-id='iscarform']")).click()
                RawData.find_element((By.XPATH,"/html/body/div[17]/div/ul/li/a/span[text()='否']")).click()
            except:
                e_CSX = '第{0}條數據車三項選擇有誤,'.format(data_index)
                fb.write(e_CSX)
                raise

            try:
                #初登日期
                Registerdate = str(listdata['初登日期'])
                RawData.find_element((By.ID, "registerdate")).send_keys(Registerdate)
            except:
                e_registerdate = '第{0}條數據初登日期有誤,'.format(data_index)
                fb.write(e_registerdate)
                raise

            try:
                #是否過戶車
                RawData.find_element((By.XPATH,"//button[@data-id='transferid']")).click()
                GHC = listdata['是否過戶車'].strip()
                RawData.find_element((By.XPATH,"/html/body/div[18]/div/ul/li/a/span[text()='"+GHC+"']")).click()
            except:
                e_GHC = '第{0}條數據過戶車選擇有誤,'.format(data_index)
                fb.write(e_GHC)
                raise

            try:
                #數據條數
                DataNum = str(int(listdata['數據條數']))
                # DataNum = re.search('\d+',listdata['數據條數']).group()
                RawData.find_element((By.ID, "commertshu")).send_keys(DataNum)
            except:
                e_DataNum = '第{0}條數據數據條數有誤,'.format(data_index)
                fb.write(e_DataNum)
                raise

            try:
                #是不是異地車
                RawData.find_element((By.XPATH,"/html/body/div[1]/div[3]/div/div[2]/div[2]/div[2]/form/div[1]/table/tbody/tr[39]/td[2]/div/button")).click()
                YDC = listdata['是否異地車'].strip()
                RawData.find_element((By.XPATH,"/html/body/div[19]/div/ul/li/a/span[text()='"+YDC+"']")).click()
            except:
                e_YDC = '第{0}條數據異地車選擇有誤,'.format(data_index)
                fb.write(e_YDC)
                raise

            # 保單系數算法
            RawData.find_element((By.XPATH,"//button[@data-id='case_type2']")).click()
            RawData.find_element((By.XPATH,"/html/body/div[20]/div/ul/li/a/span[text()='新']")).click()

            # 多年車貸
            RawData.find_element((By.XPATH,"/html/body/div[1]/div[3]/div/div[2]/div[2]/div[2]/form/div[1]/table/tbody/tr[40]/td[4]/div/button")).click()
            RawData.find_element((By.XPATH,"/html/body/div[21]/div/ul/li/a/span[text()='否']")).click()


            try:
                #提交公司代碼
                RawData.find_element((By.XPATH,"/html/body/div[1]/div[3]/div/div[2]/div[2]/div[2]/form/div[1]/table/tbody/tr[41]/td[2]/div/button")).click()
                ComCode = listdata['本公司名稱'].replace(' ','-').strip()
                RawData.find_element((By.XPATH, "/html/body/div[22]/div/ul/li/a/span[text()='"+ ComCode +"']")).click()
            except:
                e_ComCode = '第{0}條數據公司代碼有誤,'.format(data_index)
                fb.write(e_ComCode)
                raise
            #點擊提交
            RawData.find_element((By.XPATH,"//button[text()='提交']")).click()
            # time.sleep(3)
            RawData.find_element((By.XPATH,"//button[text()='肯定']")).click()
            #刷新商業數據生成頁面
            RawData.find_element((By.ID, 'main_treeDemo_34_9_span')).click()
            # 成功條數d
            succ_num += 1
            time.sleep(0.5)
            e_succ = '第{0}條數據生成成功'.format(data_index) + '\n'
            fb.write(e_succ)
        except:
            e_fail = '數據生成失敗,請校驗數據。\n’
            fb.write(e_fail)
            # 刷新商業數據生成頁面
            RawData.find_element((By.ID, 'main_treeDemo_34_9_span')).click()
            fail_num +=1
            time.sleep(0.5)
    fb.write('\n本次數據條數共{0}條,成功{1}條,失敗{2}條。\n'.format(NUM - 1, succ_num, fail_num))
    fb.close()
if __name__== '__main__':
    login()

  代碼比較簡單,不喜勿噴,本人正在學習階段!函數

  Python學習交流QQ羣:25452556,歡迎你們加入(羣主就是重寫代碼那位)!學習

相關文章
相關標籤/搜索