<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          搞定Selenium自動(dòng)化測(cè)試圖片滑塊驗(yàn)證碼了??!

          共 12374字,需瀏覽 25分鐘

           ·

          2024-07-10 08:20

          這篇文章主要是用selenium解決滑塊驗(yàn)證碼的個(gè)別案列。


          思路:

          • 用selenium打開瀏覽器指定網(wǎng)站

          • 將殘缺塊圖片和背景圖片下載到本地

          • 對(duì)比兩張圖片的相似地方,計(jì)算要滑動(dòng)的距離

          • 規(guī)劃路線,移動(dòng)滑塊



          01
          實(shí)現(xiàn)步驟


          01
          用selenium打開瀏覽器瀏覽指定網(wǎng)站


          1、找到chromedriver.exe的路徑

          點(diǎn)擊開始找到谷歌圖標(biāo)==》右鍵更多==》打開文件位置==》右鍵谷歌快捷方式==》屬性 ==》打開文件所在的位置 ==》復(fù)制路徑


          2、代碼

          from selenium import webdriver

          # chrome_path要改成你自己的路徑

          chrome_path = r"C:\Users\11248\AppData\Local\Google\Chrome\Application\chromedriver.exe"

          url = 'https://icas.jnu.edu.cn/cas/login'

          driver = webdriver.Chrome(chrome_path)

          driver.get(url)

          02
          將殘缺塊圖片和背景圖片下載到本地



          1、找到圖片位置

          打開網(wǎng)頁(yè)進(jìn)入開發(fā)者工具,找到圖片位置


          2、代碼

          import time

          import requests

          from PIL import Image

          from selenium.webdriver.common.by import By

          from io import BytesIO


          time.sleep(5)# 進(jìn)入頁(yè)面要停留幾秒鐘,等頁(yè)面加載完

          target_link = driver.find_element(By.CLASS_NAME, "yidun_bg-img").get_attribute('src')

          template_link = driver.find_element(By.CLASS_NAME, "yidun_jigsaw").get_attribute('src')


          target_img = Image.open(BytesIO(requests.get(target_link).content))

          template_img = Image.open(BytesIO(requests.get(template_link).content))

          target_img.save('target.jpg')

          template_img.save('template.png')

          03

          對(duì)比兩張圖片的相似地方,計(jì)算要滑動(dòng)的距離




          1、用matchTemplate獲取移動(dòng)距離

          因?yàn)楸尘皥D片中的殘缺塊位置和原始?xì)埲眻D的亮度有所差異,直接對(duì)比兩張圖片相似的地方,往往得不到令人滿意的結(jié)果,在此要對(duì)兩張圖片進(jìn)行一定的處理,為了避免這種亮度的干擾,筆者這里將兩張圖片先進(jìn)行灰度處理,再對(duì)圖像進(jìn)行高斯處理,最后進(jìn)行邊緣檢測(cè)。

          def handel_img(img):

              imgGray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)  # 轉(zhuǎn)灰度圖

              imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1)  # 高斯模糊

              imgCanny = cv2.Canny(imgBlur, 60, 60)  # Canny算子邊緣檢測(cè)

              return imgCanny

          將JPG圖像轉(zhuǎn)變?yōu)?通道RGBA

          def add_alpha_channel(img):

              """ 為jpg圖像添加alpha通道 """

              r_channel, g_channel, b_channel = cv2.split(img)  # 剝離jpg圖像通道

              alpha_channel = np.ones(b_channel.shape, dtype=b_channel.dtype) * 255  # 創(chuàng)建Alpha通道

              img_new = cv2.merge((r_channel, g_channel, b_channel, alpha_channel))  # 融合通道

              return img_new

          2、代碼

          import cv2

          # 讀取圖像

          def match(img_jpg_path, img_png_path):

              # 讀取圖像

              img_jpg = cv2.imread(img_jpg_path, cv2.IMREAD_UNCHANGED)

              img_png = cv2.imread(img_png_path, cv2.IMREAD_UNCHANGED)

              # 判斷jpg圖像是否已經(jīng)為4通道

              if img_jpg.shape[2] == 3:

                  img_jpg = add_alpha_channel(img_jpg)

              img = handel_img(img_jpg)

              small_img = handel_img(img_png)

              res_TM_CCOEFF_NORMED = cv2.matchTemplate(img, small_img, 3)

              value = cv2.minMaxLoc(res_TM_CCOEFF_NORMED)

              value = value[3][0]  # 獲取到移動(dòng)距離

              return value

          3、檢驗(yàn)效果

          為了驗(yàn)證思路和方法是否得當(dāng),這里將滑塊圖片與背景圖片進(jìn)行拼接,為后面埋下一個(gè)小坑。

          def merge_img(jpg_img, png_img, y1, y2, x1, x2):

              """ 將png透明圖像與jpg圖像疊加

                  y1,y2,x1,x2為疊加位置坐標(biāo)值

              """

              # 判斷jpg圖像是否已經(jīng)為4通道

              if jpg_img.shape[2] == 3:

                  jpg_img = add_alpha_channel(jpg_img)

              # 獲取要覆蓋圖像的alpha值,將像素值除以255,使值保持在0-1之間

              alpha_png = png_img[yy1:yy2, xx1:xx2, 3] / 255.0

              alpha_jpg = 1 - alpha_png


              # 開始疊加

              for c in range(0, 3):

                  jpg_img[y1:y2, x1:x2, c] = ((alpha_jpg * jpg_img[y1:y2, x1:x2, c]) + (alpha_png * png_img[yy1:yy2, xx1:xx2, c]))


              return jpg_img

              

          img_jpg_path = 'target.jpg'  # 讀者可自行修改文件路徑

          img_png_path = 'template.png'  # 讀者可自行修改文件路徑

          x1 = match(img_jpg_path, img_png_path)

          y1 = 0

          x2 = x1 + img_png.shape[1]

          y2 = y1 + img_png.shape[0]

          # 開始疊加

          res_img = merge_img(img_jpg, img_png, y1, y2, x1, x2)

          cv2.imshow("res_img ", res_img)

          cv2.waitKey(0)

          04
          規(guī)劃路線,移動(dòng)滑塊



          1、點(diǎn)擊滑塊移動(dòng)

          用第3節(jié)已經(jīng)獲取到的距離,點(diǎn)擊滑塊進(jìn)行移動(dòng)

          from selenium.webdriver.support import expected_conditions as EC

          from selenium.webdriver.support.wait import WebDriverWait

          from selenium.webdriver import ActionChains


          def crack_slider(distance):

          wait = WebDriverWait(driver, 20)

              slider = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'yidun_slider')))

              ActionChains(self.driver).click_and_hold(slider).perform()

              ActionChains(self.driver).move_by_offset(xoffset=distance, yoffset=0).perform()

              time.sleep(2)

              ActionChains(self.driver).release().perform()

              return 0

          神奇的事情是,坑來(lái)了,沒有匹配成功。


          2、匹配失敗原因

          這里有以下兩點(diǎn)原因:

          • 圖片尺寸發(fā)生了變化,距離要進(jìn)行轉(zhuǎn)換。

          • 滑塊滑動(dòng)時(shí),滑塊和殘缺塊的相對(duì)位置有變動(dòng)。

          首先解決圖片尺寸變化問題,找到網(wǎng)頁(yè)中圖片大小:345x172.500


          下載到本地圖片大?。?span style="outline: 0px;color: rgb(255, 0, 0);">480x240


          所以要對(duì)距離進(jìn)行以下處理:

          distance = distance / 480 * 345

          關(guān)于第二個(gè)問題,這里沒有找到很好的測(cè)量工具測(cè)量出來(lái),好在驗(yàn)證碼對(duì)位置精確度要求不高,就一個(gè)個(gè)試數(shù)吧。

          distance = distance /480 * 345 + 12

          05
          補(bǔ)充



          在對(duì)極驗(yàn)驗(yàn)證碼進(jìn)行學(xué)習(xí)中,有的網(wǎng)站對(duì)移動(dòng)軌跡進(jìn)行了驗(yàn)證,如果滑動(dòng)太快,也會(huì)被識(shí)別出機(jī)器操作,為了模擬人工操作,出色的程序員寫出了一個(gè)魔幻移動(dòng)軌跡


          舉個(gè)例子:我們可以先超過目標(biāo),再往回移動(dòng)。

          def get_tracks(distance):

               distance += 20

               v = 0

               t = 0.2

               forward_tracks = []

               current = 0

               mid = distance * 3 / 5

               while current < distance:

                   if current < mid:

                       a = 2

                   else:

                       a = -3

                   s = v * t + 0.5 * a * (t ** 2)

                   v = v + a * t

                   current += s

                   forward_tracks.append(round(s))


               back_tracks = [-3, -3, -2, -2, -2, -2, -2, -1, -1, -1]

               return {'forward_tracks': forward_tracks, 'back_tracks': back_tracks}



            def crack_slider(tracks):

              wait = WebDriverWait(driver, 20)

                slider = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'yidun_slider')))

                ActionChains(driver).click_and_hold(slider).perform() # 模擬按住鼠標(biāo)左鍵


                for track in tracks['forward_tracks']:

                    ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform()


                time.sleep(0.5)

                for back_tracks in tracks['back_tracks']:

                    ActionChains(driver).move_by_offset(xoffset=back_tracks, yoffset=0).perform()


                ActionChains(driver).move_by_offset(xoffset=-4, yoffset=0).perform()

                ActionChains(driver).move_by_offset(xoffset=4, yoffset=0).perform()

                time.sleep(0.5)


                ActionChains(driver).release().perform()# 釋放左鍵

                return 0

          06
          完整代碼



          # coding=utf-8

          import re

          import requests

          import time

          from io import BytesIO


          import cv2

          import numpy as np

          from PIL import Image

          from selenium import webdriver

          from selenium.webdriver import ActionChains

          from selenium.webdriver.common.by import By

          from selenium.webdriver.support import expected_conditions as EC

          from selenium.webdriver.support.wait import WebDriverWait



          class CrackSlider():

              # 通過瀏覽器截圖,識(shí)別驗(yàn)證碼中缺口位置,獲取需要滑動(dòng)距離,并破解滑動(dòng)驗(yàn)證碼


              def __init__(self):

                  super(CrackSlider, self).__init__()

                  self.opts = webdriver.ChromeOptions()

                  self.opts.add_experimental_option('excludeSwitches', ['enable-logging'])

                  # self.driver = webdriver.Chrome(ChromeDriverManager().install(), options=self.opts)

                  chrome_path = r"C:\Users\11248\AppData\Local\Google\Chrome\Application\chromedriver.exe"

                  self.driver = webdriver.Chrome(chrome_path, options=self.opts)


                  self.url = 'https://icas.jnu.edu.cn/cas/login'

                  self.wait = WebDriverWait(self.driver, 10)


              def get_pic(self):

                  self.driver.get(self.url)

                  time.sleep(5)

                  target_link = self.driver.find_element(By.CLASS_NAME, "yidun_bg-img").get_attribute('src')

                  template_link = self.driver.find_element(By.CLASS_NAME, "yidun_jigsaw").get_attribute('src')


                  target_img = Image.open(BytesIO(requests.get(target_link).content))

                  template_img = Image.open(BytesIO(requests.get(template_link).content))

                  target_img.save('target.jpg')

                  template_img.save('template.png')


              def crack_slider(self, distance):

                  slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'yidun_slider')))

                  ActionChains(self.driver).click_and_hold(slider).perform()

                  ActionChains(self.driver).move_by_offset(xoffset=distance, yoffset=0).perform()

                  time.sleep(2)

                  ActionChains(self.driver).release().perform()

                  return 0



          def add_alpha_channel(img):

              """ 為jpg圖像添加alpha通道 """


              r_channel, g_channel, b_channel = cv2.split(img)  # 剝離jpg圖像通道

              alpha_channel = np.ones(b_channel.shape, dtype=b_channel.dtype) * 255  # 創(chuàng)建Alpha通道


              img_new = cv2.merge((r_channel, g_channel, b_channel, alpha_channel))  # 融合通道

              return img_new



          def handel_img(img):

              imgGray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)  # 轉(zhuǎn)灰度圖

              imgBlur = cv2.GaussianBlur(imgGray, (5, 5), 1)  # 高斯模糊

              imgCanny = cv2.Canny(imgBlur, 60, 60)  # Canny算子邊緣檢測(cè)

              return imgCanny



          def match(img_jpg_path, img_png_path):

              # 讀取圖像

              img_jpg = cv2.imread(img_jpg_path, cv2.IMREAD_UNCHANGED)

              img_png = cv2.imread(img_png_path, cv2.IMREAD_UNCHANGED)

              # 判斷jpg圖像是否已經(jīng)為4通道

              if img_jpg.shape[2] == 3:

                  img_jpg = add_alpha_channel(img_jpg)

              img = handel_img(img_jpg)

              small_img = handel_img(img_png)

              res_TM_CCOEFF_NORMED = cv2.matchTemplate(img, small_img, 3)

              value = cv2.minMaxLoc(res_TM_CCOEFF_NORMED)

              value = value[3][0]  # 獲取到移動(dòng)距離

              return value

              


          # 1. 打開chromedriver,試試下載圖片

          cs = CrackSlider()

          cs.get_pic()

          # 2. 對(duì)比圖片,計(jì)算距離

          img_jpg_path = 'target.jpg'  # 讀者可自行修改文件路徑

          img_png_path = 'template.png'  # 讀者可自行修改文件路徑

          distance = match(img_jpg_path, img_png_path)

          distance = distance /480 * 345 + 12

          # 3. 移動(dòng)

          cs.crack_slider(distance)

          轉(zhuǎn)載自:https://blog.csdn.net/qq_44419449/article/details/127414044

          自動(dòng)化專欄開課報(bào)名了自動(dòng)化測(cè)試全攻略:從入門到精通!


          推薦閱讀:

          1. 重磅發(fā)布!2024年全棧測(cè)試開發(fā)實(shí)戰(zhàn)指南(第5期),技能進(jìn)階必備!

          2. 史上最全測(cè)試開發(fā)工具推薦(含自動(dòng)化、APP性能、穩(wěn)定性、抓包神器)

          3. 推薦幾款常用測(cè)試數(shù)據(jù)自動(dòng)生成工具(適用自動(dòng)化測(cè)試、性能測(cè)試)

          END

          所有原創(chuàng)文章
          第一時(shí)間發(fā)布至此公眾號(hào)「測(cè)試開發(fā)技術(shù)」

          長(zhǎng)按二維碼/微信掃碼  添加作者

          瀏覽 123
          2點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          2點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青青视频网 | 男人天堂网在线 | 狠狠干在线观看 | 婷婷综合网 | 波多野结衣在线天堂 |