亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

首頁 慕課教程 Scrapy 入門教程 Scrapy 入門教程 Selenium 自動化測試工具介紹

Selenium 自動化測試工具介紹

今天我們來介紹下 Selenium 自動化測試工具并借助該工具完成一個簡單的案例,這個案例和筆者的工作相關,也算挺有意思的。

1. Selenuim 介紹與使用

Selenium 是一個用于 Web 應用程序自動化測試工具,提供一系列的測試函數。這些函數非常靈活,能夠完成界面元素定位、窗口跳轉、結果比較。Selenium 測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。該自動化測試工具具有如下幾個鮮明的特點:

  • 支持多種瀏覽器:IE、Firefox、Safari、Chrome 等主流瀏覽器都是支持的;
  • 支持多種變成語言:支持主流的編程語言,如 Java、Python、Ruby、PHP 等;
  • 支持多種操作系統:如 Windows、Linux、IOS 以及 Android 等;
  • 開源免費:selenuim 在 github 上進行了開源,star 和 fork 數都彰顯了該項目的流行度。Selenium框架由多個工具組成,包括:Selenium IDE,Selenium RC,Selenium WebDriver和SeleniumRC。

我們直接來在使用 Python 操作 Selenuim:

安裝 selenium 模塊:pip install selenium -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com;

接下來,我們要使用 Google 瀏覽器完成 selenium 的自動化操作,因此需要安裝相應的 webdriver。對應 Google 瀏覽器的 webdriver 的下載地址為:下載。找到對應的 Chrome driver 版本,下載即可:

圖片描述

本地 chrome 版本查看

圖片描述

選擇 webdriver 版本

下載了 webdriver 包后解壓得到 chromedriver.exe,將其放到和 Chrome 瀏覽器相同的路徑下:
圖片描述

解壓chromedriver包,將exe文件放到chrome的目錄下去

接下來將上面的這個路徑添加到系統變量 Path 中去,確保能找到 chromedriver.exe 這個文件:
圖片描述

添加 chromedriver.exe 所在目錄到Path變量中去

?

接下來,我們完成一段簡單的 Selenium 自動化測試代碼,幫助我們更好的理解 Selenium 這個工具:

"""
selenium工具測試
"""
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


driver = webdriver.Chrome()
# 請求百度頁面
driver.get("https://www.baidu.com") 

# 找到輸入框位置
input = driver.find_element_by_id("kw")
# 輸入"慕課網 wiki寶典"
input.send_keys("慕課網 wiki寶典")
# 找到<百度一下>按鈕
button = driver.find_element_by_id("su")
# 點擊
button.click()

# 直到出現分頁元素
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "page"))
)
# 找到搜索內容的第一條結果
wiki_page = driver.find_element_by_xpath('//div[@id="content_left"]/div[1]/h3/a')
# 點擊跳轉到慕課網的wiki頁面
wiki_page.click()

上面的代碼比較簡單,我們只需要了解下 selenium 工具提供的基本函數就能夠理解,代碼中已經做好了相關注釋,我們直接來運行看看效果如何:

是不是有點意思?這段代碼幫我們自動啟動 Chrome 瀏覽器,跳轉到百度頁面,然后再輸入框中輸入 “慕課網 wiki”,然后點擊百度一下。在搜索的頁面中選擇第一個點擊,進入到慕課網的 wiki 頁面中。這整個過程就是由代碼控制完成,沒有人為操作,這是不是就是我們想象的自動化測試呢?自信點,就是這樣的!

2. 基于 Selenium 完成發票認證

接下來,我們基于 Scrapy 和 Selenium 來完成筆者工作中的一個需求。我們每個月有一筆通信發票的報銷,需要使用對自己在營業廳中買的發票進行校驗,然后要截圖留存。報銷的時間有時候是3個月一次,有時候是半年,所以累積下來有不少發票,這些發票都需要校驗和截圖才能報銷。

我們應屆生剛工作的時候,我們大部分新員工都是手工截圖,非常笨拙,且耗時。由于是搞技術的公司,于是有前端人員寫了相關的前端插件來自動化截圖和生成發票校驗文檔,然后在公司內廣泛應用。我也寫了這樣一段基于 Selenium 的自動化截圖代碼,不過代碼依賴 chrome 和 webdriver,所以組內的部分人會把發票的起始編號和張數發給我,我運行程序截好圖后將圖片打包發給他們自己放到 word 文檔中去。

來看看發票校驗的網站的截圖如下:

圖片描述

廣東通信發票校驗網站

驗證的方式非常機械,正是因為機械操作,才給了我們自動化的可能、看上圖中的四個輸入框,表示的含義分別為:

  • 發票代碼:固定值;
  • 發票號碼:通常而言,從移動營業廳拿的通信發票是連續的,這樣就可以用 for 循環實現;
  • 納稅人識別號:這個是個固定值;
  • 發票面額:固定50元。假設我買300元的卡,就會對應6張發票;

我們填好每張發票的相應信息,只有一個變量。在查詢之前,需要先拖動滑塊進行驗證,驗證通過,再點擊查詢就可以進行認證。得到了認證結果后,截張圖,如此進行下去,直到所有的發票都校驗截圖完畢。令人欣慰的是這里的滑塊驗證只需要做一次,得到了相應的認證截圖后,每次調整下一張發票的發票號碼,在截一張圖即可??聪旅娴淖龇ǎ?/p>

因此,我們得到了這樣的機械化動作:

  • 打開發票校驗頁面;
  • 輸入第一張發票的四個參數,然后拖動滑塊到最右端完成校驗;
  • 截圖留存;
  • 改動第二個輸入框的發票號碼,為下一個發票編號,然后直接截圖;重復,直到最后一張發票截圖成功;

對應這樣的動作我們翻譯成相應的 Selenium 自動化代碼如下:

"""
測試 selenium 工具
"""
import time
import random

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains


# 固定值
ticket_code = "144011690802"
identification_number = "91440101618652334F"
face_value = 50

# 起始編號
ticket_start_num = 15415104
# 發票總數
total_count = 10


def click_space(driver):
    """
    點擊下空白處,使得輸入框失去焦點
    """
    driver.find_elements_by_xpath('//div[@class="check-main"]/table/tbody/tr[1]/td[1]')[0].click()


def fill_input(driver, idx):
    """
    填充輸入框
    """
    input_value = [ticket_code, idx, identification_number, face_value]
    table = driver.find_elements_by_xpath('//div[@class="check-main"]/table/tbody')[0]
    for i in range(1, len(input_value) + 1):
        input = table.find_elements_by_xpath(f'./tr[{i}]/td[2]/input')[0] 
        input.clear()
        input.send_keys(input_value[i - 1])
    click_space(driver)


def get_track(distance):      
    """
    參考文獻2代碼,模擬人移動鼠標
    :distance為傳入的總距離
    """
    # 移動軌跡
    track = []
    # 當前位移
    current = 0
    # 減速閾值
    mid = distance * 3 / 5
    # 計算間隔
    t = 0.4
    # 初速度
    v = 1

    while current < distance:
        if current < mid:
            # 加速度為一個隨機值
            a = random.randint(2, 6)
        else:
            # 加速度為一個隨機負值
            a = -1 * random.randint(1, 2)
        v0 = v
        # 當前速度
        v = v0 + a * t
        # 移動距離
        move = v0 * t + 0.5 * a * t * t
        # 當前位移
        current += move
        # 加入軌跡
        track.append(round(move))
    return track


def move_to_gap(slider, tracks):
    """
    參考文獻2代碼
    :slider是要移動的滑塊,tracks是要傳入的移動軌跡
    """
    action = ActionChains(driver)
    action.click_and_hold(slider).perform()
    for x in tracks:
        ActionChains(driver).move_by_offset(xoffset=x,yoffset=0).perform()
    time.sleep(0.1)
    ActionChains(driver).release().perform()

# 發票校驗地址
verify_address = "https://gs.etax-gd.gov.cn/gsyw/service/fpyw/fpcy/index"

# 想屏蔽selenium標識,避免被服務端檢測到,似乎沒起作用
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ['enable-automation'])
driver = webdriver.Chrome(options=options, executable_path="C:/Users/spyinx/AppData/Local/Google/Chrome/Application/chromedriver.exe")
driver.maximize_window()

# 第一步先去發票查詢頁面
driver.get(verify_address)

# 等待滑塊出現
WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, 'nc_1_n1z'))
)

# 填充輸入框
fill_input(driver, ticket_start_num)
# 等待幾秒后
driver.implicitly_wait(5)

# 找到滑動按鈕,模擬鼠標按下不松開
slider = driver.find_element_by_id('nc_1_n1z')
move_to_gap(slider, get_track(300))

driver.implicitly_wait(2)
driver.find_element_by_id("CxBtn").click()

# 查詢第一個需要滑動滑塊
driver.get_screenshot_as_file(f"{ticket_start_num}.png")

for i in range(1, total_count):
    ticket_num = ticket_start_num + i
    fill_input(driver, ticket_num)
    driver.get_screenshot_as_file(f"{ticket_num}.png")
    driver.implicitly_wait(1)

上面的代碼已經做好了詳細的注釋,請查找相關資料了解 Selenium 提供的相關方法,比如定位頁面元素的方法、對頁面元素點擊(click)、輸入框情況 (clear) 以及輸入元素(send_keys) 以及鼠標的相關操作方法。下面我們直接來看代碼的演示效果,最后的截圖也全部得到。

注意:由于這個滑動驗證碼是接入的阿里滑動驗證碼插件,具備超強的反爬蟲能力,能識別出是瀏覽器否被 selenium 控制。本次測試重復了無數次,才終于有一次沒有出現滑塊校驗錯誤,才成功錄下此視頻。具體的可以搜索大神如何破解阿里的滑動驗證碼,不過大部分代碼已經過時,無法突破驗證。

總而言之,上面的操作是不是一定程度上能幫助我們減少手工操作,節約了時間成本?如果大家感興趣的話,可以嘗試使用 Selenium 完成京東商城的自動登錄操作,這里會有滑動圖片缺口補全的校驗,會稍微有點復雜,對你們來說也是一個不錯的挑戰。

3. 小結

本小節中我們介紹了自動化工具 Selenuim 的使用, 同時結合 Scrapy 框架了完成了一個簡單的案例。這個案例來源于筆者公司的一個小需求,學習好技術有時能給我們工作和生活帶來許多意想不到的驚喜,這也是我們能不斷追求技術的一個動力。