【自動化測試例項】
# -*- coding: utf-8 -*- import time import requests import re import pytesseract from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from PIL import Image, ImageEnhance from settings import USERNAME, PASSWORD, PACKAGE_PATH, CHROME_WEBDRIVER_PATH from selenium.webdriver.chrome.options importOptions class WebAuto(object): def __init__(self): # 加上以下程式碼就是無視窗化執行 chrome_options = Options() chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument('--headless') # ########################self.wd = webdriver.Chrome(CHROME_WEBDRIVER_PATH, options=chrome_options) self.wd.implicitly_wait(20) self.ac = ActionChains(self.wd) self.wd.get('http://xxx.xxx.xxx/') def get_picture(self): """通過截圖獲取驗證碼圖片""" self.wd.implicitly_wait(3) time.sleep(3) self.wd.save_screenshot('picture.png') # 截圖螢幕 page_snap_obj = Image.open('picture.png') # 開啟截圖 elements = self.wd.find_elements_by_xpath("/html/body/div/div/div/*") element = elements[1] elements = element.find_elements_by_class_name('el-form-item') element = elements[2] elements = element.find_elements_by_xpath('//form/div/div/div/img') # img = elements[0] img = element.find_element_by_class_name('validcode') location = img.location size = img.size left = location['x'] * 2 top = location['y'] * 2 right = left + size['width'] * 2 bottom = top + size['height'] * 2 img_obj = page_snap_obj.crop((left, top, right, bottom)) time.sleep(2) return img_obj def get_picture2(self): """通過動態獲取圖片src屬性獲取驗證碼圖片--準確率高""" elements = self.wd.find_elements_by_class_name('validcode') time.sleep(3) element = elements[0] url = element.get_attribute('src') r = requests.get(url) with open('picture.png', 'wb')as f: f.write(r.content) img_obj = Image.open('picture.png') return img_obj def processing_image(self): """處理圖片""" img = self.get_picture() img = img.convert("L") # 轉灰度 pixdata = img.load() w, h = img.size threshold = 160 # 遍歷所有畫素,大於閾值的為黑色 for y in range(h): for x in range(w): if pixdata[x, y] < threshold: pixdata[x, y] = 0 else: pixdata[x, y] = 255 return img def delete_spot(self): """處理圖片""" images = self.processing_image() data = images.getdata() w, h = images.size black_point = 0 for x in range(1, w - 1): for y in range(1, h - 1): mid_pixel = data[w * y + x] # 中央畫素點畫素值 if mid_pixel < 50: # 找出上下左右四個方向畫素點畫素值 top_pixel = data[w * (y - 1) + x] left_pixel = data[w * y + (x - 1)] down_pixel = data[w * (y + 1) + x] right_pixel = data[w * y + (x + 1)] if top_pixel < 10: black_point += 1 if left_pixel < 10: black_point += 1 if down_pixel < 10: black_point += 1 if right_pixel < 10: black_point += 1 if black_point < 1: images.putpixel((x, y), 255) black_point = 0 return images def image_str(self): """驗證碼圖片轉字串""" image = self.delete_spot() # pytesseract.pytesseract.tesseract_cmd = r'/usr/local/Cellar/tesseract/4.1.1/tesseract' result = pytesseract.image_to_string(image) resultj = re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])", "", result) result_four = resultj[0:4] print('驗證碼:', resultj) return result_four # def image_str2(self): # """驗證碼圖片轉字串--識別效率太低""" # image = self.delete_spot() # image.load() # image.split() # vcode = pytesseract.image_to_string(image) # print(len(vcode)) # return vcode # # def image_str3(self): # """驗證碼圖片轉字串--識別效率太低""" # img = self.get_picture2() # img = img.convert('RGB') # 這裡也可以嘗試使用L # enhancer = ImageEnhance.Color(img) # enhancer = enhancer.enhance(0) # enhancer = ImageEnhance.Brightness(enhancer) # enhancer = enhancer.enhance(2) # enhancer = ImageEnhance.Contrast(enhancer) # enhancer = enhancer.enhance(8) # enhancer = ImageEnhance.Sharpness(enhancer) # img = enhancer.enhance(20) # code = pytesseract.image_to_string(img) # return code def login(self): """登陸""" # 登陸流程 elements = self.wd.find_elements_by_xpath("/html/body/div/div/div/*") input = elements[1].find_elements_by_class_name('el-input__inner') # 輸入使用者名稱,密碼 input[0].send_keys(USERNAME) input[1].send_keys(PASSWORD) code = self.image_str() input[2].send_keys(code) time.sleep(5) elements = elements[1].find_elements_by_xpath('//div/form/*') button = elements[7].find_elements_by_xpath('//div/button') login_container = self.wd.find_element_by_id("loginFormId") login_container.find_elements_by_class_name("form-item-tittle") # 點選登陸 button[0].click() time.sleep(5) # 獲取所有cookie cookies = self.wd.get_cookies() if len(cookies) == 1: # 登陸失敗 cookie只有一條 self.wd.quit() self.__init__() self.login() else: # 登陸成功 我測試cookie有三條 pass def create(self): """建立策略""" # 防止頁面未跳轉 就已經開始尋找標籤 會報錯 time.sleep(3) # 點選下拉選單 print('登陸成功') menus = self.wd.find_elements_by_class_name('el-submenu__title') menu = menus[1] e1 = menu.find_elements_by_class_name("el-icon-ijiami-aab")[0] self.ac.click(e1).perform() time.sleep(3) # 點選 elements = self.wd.find_elements_by_class_name('el-menu-item') element = elements[4] element.click() time.sleep(3) # create_button create_button = self.wd.find_elements_by_class_name('el-form-item__content') create_button[0].click() time.sleep(3) # 上傳aab檔案 inputs = self.wd.find_elements_by_class_name("el-upload__input") input = inputs[0] time.sleep(3) # 策略名=包名 # path = package_path path = PACKAGE_PATH input.send_keys(path) time.sleep(3) # 用.el-dialog__footer的數量來判斷是否上傳完成 # 上傳完成3個/未上傳2個 while 1: footer = self.wd.find_elements_by_class_name('el-dialog__footer') time.sleep(2) if len(footer) == 3: print('上傳檔案完成') break # 策略名 name = path.split('/')[-1] print('策略名:', name) inputs = self.wd.find_elements_by_class_name('el-input__inner') input = inputs[8] input.send_keys(name) # 配置策略 settings = self.wd.find_elements_by_class_name('el-radio-group') s1 = settings[10] # 加密全部 s2 = settings[13] # hook框架檢測 s3 = settings[15] # 防trace分析 s1.click() s2.click() s3.click() # 提交 submits = self.wd.find_elements_by_class_name('el-button--primary') submit = submits[4] submit.click() print("建立策略成功") def main(self): # self.get_picture2() self.login() self.create() self.wd.quit() if __name__ == '__main__': webauto = WebAuto() webauto.main()
-- 本次的需求是自動化登陸網頁並有一定的操作,包括上傳檔案等等,整個過程相對比較簡單,但是有幾個小點需要注意
-- webdriver是分版本的,它有macos/linux/windows三個版本,剛開始在macos上寫程式碼,最後在linux上跑程式碼,需要切換webdriver
-- python3的PIL其實就是Pillow只不過python2叫PIL
-- 要讓selemium在linux命令列執行,有兩種方式,第一是虛擬化一個視窗,第二是設定無視窗的執行,本次採用的是第二種嗎,在配置webdriver之前要加如下程式碼
# 加上以下程式碼就是無視窗化執行 chrome_options = Options() chrome_options.add_argument('--no-sandbox') chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument('--headless') # ######################## self.wd = webdriver.Chrome(CHROME_WEBDRIVER_PATH, options=chrome_options)
-- 獲取驗證碼儘量採取src屬性的形式來獲取,如果採用截圖的方式來獲取,出問題的概率比較大
-- tesseract-orc是識別驗證碼轉字串的庫,python對於的是pytesseract,但是這個python庫是依賴與tesseract-orc的,而且這個程式分版本,要先下載好
-- 判斷頁面跳轉我用的是cookies,在此程式碼中登陸之前使用者只有一條cookie,登陸之後使用者有三條cookie,用此來判斷使用者是不是已經登陸成功了。對應的selenium是webdriver.get_cookies()方法,它的返回值是一個列表。
-- 在頁面點選無效的情況下可以試試ActionChains如下方法,我也不清楚這個cilick和原始的click有什麼區別,但是這個確實實現了。
from selenium.webdriver.common.action_chains import ActionChains
self.wd = webdriver.Chrome(CHROME_WEBDRIVER_PATH, options=chrome_options) self.wd.implicitly_wait(20) self.ac = ActionChains(self.wd) self.ac.click()
-- python中的input輸入後是帶等引號的,防止被坑(如果input路徑這種,直接輸入就好了,不用加引號)
-- 拷貝檔案到阿里雲的時候,阿里雲pwd出來的路徑居然拷貝的時候報錯了,最後在root前加了一個home (/home/root)
-- pytesseract識別圖片驗證碼是有概率的,不是百分之百成功的。
-- 在用selenium尋找元素的時候,要小心frame,然後可以用chrome自帶的開發這工具中的尋找方法先在瀏覽器中測試是否能根據class/id/css等找到,再在程式碼中測,效率比較高
-- chrome中ctrl+f尋找的時候比如輸入.a1 出現了十個結果,那麼你可以找到你要的結果比如是第十個,那在程式碼中它的索引就是第九個。很方便。
-- 還有寫程式碼一定要用虛擬環境,寫完一定要在程式碼中建立requirments.txt檔案,改寫的註釋要寫,變數名見名知意。