Python +Selenium 底層API封裝(日誌+截圖管理)
阿新 • • 發佈:2019-01-24
使用:
import seleniumKing
king = seleniumKing.WebTools(path)
king.Open(URL)
直接附上原始碼:
import os import sys import time from PIL import Image, ImageFilter from pytesseract import pytesseract from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys from selenium.webdriver import ActionChains from util_s.logger import Logger from util_s.config import Config ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) sys.path.append(ROOT_DIR) class WebTools(object): """selenium 底層API相關封裝""" def __init__(self, path="webTools"): self.Time_out = 5 self.Time_poll = 0.5 self.logger = Logger(path).getlog() """ 瀏覽器相關方法: 前進,後退,重新整理,開啟,獲取Url,獲取Title """ # 前進瀏覽器 def Forward(self): self.driver.forward() self.logger.info("前進瀏覽器") # 後退瀏覽器 def Back(self): self.driver.back() self.logger.info("後退瀏覽器") # 重新整理瀏覽器 def Refresh(self): self.driver.refresh() self.logger.info("重新整理瀏覽器") # 開啟瀏覽器 def Open(self, url, browser_type=Config().get("browser_type")): if browser_type == 'Firefox': self.driver = webdriver.Firefox() elif browser_type == 'Chrome': self.driver = webdriver.Chrome() elif browser_type == 'IE': self.driver = webdriver.Ie() else: self.driver = webdriver.Chrome() self.driver.maximize_window() self.driver.implicitly_wait(5) self.driver.get(url) self.logger.info("開啟瀏覽器:" + str(self.driver).split(".")[2] + "-" + "[" + url + "]") # 關閉瀏覽器 def Quit(self): time.sleep(2) self.driver.quit() self.logger.info("關閉瀏覽器") # 關閉視窗 def Close(self): self.driver.close() self.logger.info("關閉視窗") # 獲取瀏覽器URL def Get_Url(self): time.sleep(1) url = self.driver.current_url self.logger.info("獲取瀏覽器URL:" + "[" + str(url) + "]") return url # 獲取瀏覽器Title def Get_title(self): time.sleep(1) title = self.driver.title self.logger.info("獲取瀏覽器Title:" + "[" + str(title) + "]") return title """ WebElement相關方法: 提交表單,返回元素尺寸,返回元素文字,返回屬性值,返回元素是否可見,睡眠,返回當前驗證碼 """ # 提交表單 def Submit(self, by): self.find(by).submit() self.logger.info("提交表單:By" + "[" + str(by) + "]") # 返回元素尺寸 def Get_size(self, by): time.sleep(1) size = self.find(by).size self.logger.info("返回元素尺寸:By" + "[" + str(by) + "]-" + str(size)) return size # 返回元素文字 def Get_text(self, by): time.sleep(1) text = self.find(by).text self.logger.info("返回元素尺寸:By" + "[" + str(by) + "]-" + str(text)) return text # 返回屬性值 def Get_attribute(self, by, name): time.sleep(1) attribute = self.find(by).get_attribute(name) self.logger.info("返回屬性值:By/name" + "[" + str(by) + "/" + str(name) + "]-" + str(attribute)) return attribute # 返回元素是否可見 def Get_result(self, by): time.sleep(1) result = self.find(by).is_displayed() self.logger.info("返回元素是否可見:By" + "[" + str(by) + "]-" + str(result)) return result # 返回當前驗證碼 def Get_img_test(self, by, click_by): for a in range(100): time.sleep(1) file_path = os.path.dirname(os.path.abspath('.')) + '/testOutput/screenshots/' rq = "get_element_img" screen_name = file_path + rq + '.png' imger = self.get_element_img(by) im = Image.open(imger) img = im.convert('RGBA') pix = img.load() R = 125 G = 125 B = 125 for y in range(img.size[1]): # 二值化處理,這個閾值為R=125,G=125,B=125 for x in range(img.size[0]): if pix[x, y][0] < R or pix[x, y][1] < B or pix[x, y][2] < G: pix[x, y] = (0, 0, 0, 255) else: pix[x, y] = (255, 255, 255, 255) img.save(imger) image = Image.open(imger) filterimg = image.filter(ImageFilter.MedianFilter) texts = pytesseract.image_to_string(filterimg) text = texts.lower() fomart = 'abcdefghijklmnopqrstuvwxyz0123456789' for c in texts: if c not in fomart: text = text.replace(c, '') if len(str(text)) == 4: filterimg.save(screen_name) self.logger.info("驗證碼識別:" + text + ">>>" + imger) return text time.sleep(1) self.find(click_by).click() print(str(click_by)) # 睡眠 def Sleep(self, times): time.sleep(times) self.logger.info("睡眠:" + str(times)) """ 滑鼠事件相關方法: 右擊,懸停,雙擊,拖放 """ # 右擊 def Cilck_right(self, by): ActionChains(self.driver).context_click(self.find(by)).perform() self.logger.info("右擊:By" + "[" + str(by) + "]") # 懸停 def Move_to(self, by): ActionChains(self.driver).move_to_element(self.find(by)).perform() self.logger.info("懸停:By" + "[" + str(by) + "]") # 雙擊 def Cilck_Double(self, by): ActionChains(self.driver).double_click(self.find(by)).perform() self.logger.info("雙擊:By" + "[" + str(by) + "]") # 拖放 def Go_attribute(self, by_f, by_t): ActionChains(self.driver).drag_and_drop(self.find(by_f), self.find(by_t)).perform() self.logger.info("拖放:By" + "[" + str(by_f) + "->" + str(by_t) + "]") """ 鍵盤事件相關方法: 回退字元,全選,複製,貼上, 撤銷,換行,空格,製表, 輸入,單擊,清除 """ # 回退字元 def Keys_back(self, by): self.find(by).send_keys(Keys.BACK_SPACE) self.logger.info("回退字元:By" + "[" + str(by) + "]") # 全選 def Keys_Ctrl_A(self, by): self.find(by).send_keys(Keys.CONTROL, "a") self.logger.info("全選:By" + "[" + str(by) + "]") # 複製 def Keys_Ctrl_C(self, by): self.find(by).send_keys(Keys.CONTROL, "c") self.logger.info("複製:By" + "[" + str(by) + "]") # 貼上 def Keys_Ctrl_V(self, by): self.find(by).send_keys(Keys.CONTROL, "v") self.logger.info("貼上:By" + "[" + str(by) + "]") # 撤銷 def Keys_Ctrl_Z(self, by): self.find(by).send_keys(Keys.CONTROL, "z") self.logger.info("撤銷:By" + "[" + str(by) + "]") # 換行 def Keys_Enter(self, by): self.find(by).send_keys(Keys.ENTER) self.logger.info("換行:By" + "[" + str(by) + "]") # 空格 def Keys_Space(self, by): self.find(by).send_keys(Keys.SPACE) self.logger.info("空格:By" + "[" + str(by) + "]") # 製表 def Keys_Tab(self, by): self.find(by).send_keys(Keys.TAB) self.logger.info("製表:By" + "[" + str(by) + "]") # 輸入 def Input(self, by, inputvalue): self.find(by).clear() self.find(by).send_keys(inputvalue) self.logger.info("輸入:By" + "[" + str(str(by)) + "]") # 輸入_子元素 def Input_Child(self, by, by1, inputvalue): self.find_Child(by, by1).clear() self.find_Child(by, by1).send_keys(inputvalue) self.logger.info("輸入_子元素:By" + "[" + str(by) + ">>>" + str(by1) + "]") # 單擊 def Click(self, by): self.find(by).click() self.logger.info("單擊:By" + "[" + str(by) + "]") # 單擊_子元素 def Click_Child(self, by, by1): self.find_Child(by, by1).click() self.logger.info("單擊_子元素:By" + "[" + str(by) + ">>>" + str(by1) + "]") # 清除 def Clear(self, by): self.find(by).clear() self.logger.info("清除:By" + "[" + str(by) + "]") # 清除_子元素 def Clear_Child(self, by, by1): self.find_Child(by, by1).clear() self.logger.info("清除_子元素:By" + "[" + str(by) + ">>>" + str(by1) + "]") # 確認警告框 def Alert_accept(self): self.driver.switch_to_alert().accept() self.logger.info("確認警告框") # 取消警告框 def Alert_dismiss(self): self.driver.switch_to_alert().dismiss() self.logger.info("取消警告框") # 返回警告框內容 def Get_alert_text(self): text = self.driver.switch_to_alert().text self.logger.info("返回警告框內容:" + str(text)) return text # 輸入警告框內容 def Input_alert_text(self, text): self.driver.switch_to_alert().send_keys(text) self.logger.info("輸入警告框內容:" + str(text)) # 返回所有Window控制代碼 def Get_driver_windows(self): driver_windows = self.driver.window_handles self.logger.info("返回所有Window控制代碼:" + str(driver_windows)) return driver_windows # 返回當前Window控制代碼 def Get_driver_window(self): driver_window = self.driver.current_window_handle self.logger.info("返回當前Window控制代碼:" + str(driver_window)) return driver_window # 切換Windows def Switch_window(self, window): self.driver.switch_to.window(window) self.logger.info("切換Windows:" + str(window)) # 切換Frame def Switch_frame(self, by): self.driver.switch_to.frame(by) self.logger.info("切換Frame:By" + "[" + str(by) + "]") # 查詢元素 def find(self, by): try: element = WebDriverWait(self.driver, self.Time_out, self.Time_poll, "NoFindWebelement").until( EC.presence_of_element_located(by)) return element except: log = ("未找到Webelement:By" + "[" + str(by) + "]截圖:>>>" + self.get_windows_img()) self.logger.info(log) # 查詢子元素 def find_Child(self, by, by1): try: element = self.driver.find_element(*by) time.sleep(1) element = element.find_element(*by1) return element except: log = ("未找到Webelement:By" + "[" + str(by) + ">>>" + str(by1) + "]截圖:>>>" + self.get_windows_img()) self.logger.info(log) # 查詢元素們 def finds(self, by): try: elements = WebDriverWait(self.driver, self.Time_out, self.Time_poll, "未找到Webelement").until( EC.presence_of_all_elements_located(by)) return elements except: log = ("未找到Webelement:By" + "[" + str(by) + "]截圖:>>>" + self.get_windows_img()) self.logger.info(log) # 儲存瀏覽器截圖 def get_windows_img(self): """ 在這裡我們把file_path這個引數寫死,直接儲存到我們專案根目錄的一個資料夾./testOutput/screenshots下 """ file_path = os.path.dirname(os.path.abspath('.')) + '/testOutput/screenshots/' rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time())) screen_name = file_path + rq + '.png' try: self.driver.get_screenshot_as_file(screen_name) return rq + '.png' except: self.logger.info("截圖失敗") # 儲存元素截圖 def get_element_img(self, by): """ 在這裡我們把file_path這個引數寫死,直接儲存到我們專案根目錄的一個資料夾./testOutput/screenshots下 """ file_path = os.path.dirname(os.path.abspath('.')) + '/testOutput/screenshots/' rq = "get_element_img" screen_name = file_path + rq + '.png' element = self.find(by) try: self.driver.save_screenshot(screen_name) left = element.location['x'] top = element.location['y'] right = element.location['x'] + element.size['width'] bottom = element.location['y'] + element.size['height'] im = Image.open(screen_name) im = im.crop((left, top, right, bottom)) im.save(screen_name) return screen_name except: self.logger.info("元素截圖失敗")