新版無完整背景圖片滑塊驗證碼
阿新 • • 發佈:2020-09-11
新版無完整背景圖片滑塊驗證碼
步驟:
1、將圖片灰度,兩張都要灰度
2、將圖片銳化,兩張都要銳化
3、計算2d卷積核,兩張都要計算
4、卷積結果最大的點所在區域即為與卷積核(小滑塊)邊緣重合度最高的區域。
那麼在背景圖中,與小滑塊重合度最高的區域應該為缺口區域。因此我們找到的卷積結果最大的點就是背景圖缺口的中心點。
import requests import cv2 import time import os from scipy import signal from selenium import webdriver #用來驅動瀏覽器的 from selenium.webdriver import ActionChains #破解滑動驗證碼的時候用,可拖動圖片 from selenium.webdriver.common.keys import Keys # 通過新版無原圖滑塊驗證碼 class Pass_slide: def __init__(self): self.driver = webdriver.Chrome() def input_user_pwd(self): self.driver.get('https://star.toutiao.com/') # 數字賬號密碼登入 self.driver.find_element_by_xpath('//*[@id="app"]/div/div[1]/div[2]/div[2]/div[1]').click() time.sleep(1) self.driver.find_element_by_xpath('/html/body/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[1]').click() time.sleep(1) # 輸入賬號 self.driver.find_element_by_xpath('//*[@id="account-sdk"]/section/div[3]/div[1]/div[2]/div/input').send_keys( 'username' ) # 輸入密碼 self.driver.find_element_by_xpath('//*[@id="account-sdk"]/section/div[3]/div[2]/div/div/input').send_keys( 'password' ) time.sleep(1) # 點選登入 self.driver.find_element_by_xpath('//*[@id="account-sdk"]/section/div[6]/button').click() time.sleep(1) def slide_button(self): # 定位滑塊位置 # 方式一:通過圖片定位位置 # button = self.driver.find_element_by_xpath('//*[@id="account-sdk-slide-container"]/div/div[2]/img[2]') # 方式二: 用 Xpath 定位位置 # button = self.driver.find_element_by_xpath( # '//*[@id="account-sdk-slide-container"]/div/div[3]/div[2]/div[2]/div' # ) # 方式三:通過 class 來定位 button = self.driver.find_element_by_class_name('sc-jKJlTe') time.sleep(1) return button def move_to_slide(self,distance): # tracks是要傳入的移動軌跡 ActionChains(self.driver).click_and_hold(self.slide_button()).perform() # 移動 for x in self.track(distance): ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform() time.sleep(0.3) ActionChains(self.driver).release().perform() def track(self, distance): # distance為傳入的總距離 # 移動軌跡 track = [] current = 0 # 當前位移 mid = distance * 4 / 5 # 減速閾值 t = 0.2 # 計算間隔 v = 1 # 初速度 while current < distance: if current < mid: a = 4 # 加速度為2 else: a = -3 # 加速度為-2 v0 = v v = v0 + a * t # 當前速度 move = v0 * t + 1 / 2 * a * t * t # 移動距離 current += move # 當前位移 track.append(round(move)) # 加入軌跡 return track def download_slide_auth_code_img(self): # 下載滑塊,和背景缺口圖片 if not os.path.exists('./Auth_Slide_Img'): os.mkdir('./Auth_Slide_Img') big_img_url = self.driver.find_element_by_xpath( '//*[@id="account-sdk-slide-container"]/div/div[2]/img[1]').get_attribute('src') # 缺口背景圖片 地址 small_img_url = self.driver.find_element_by_xpath( '//*[@id="account-sdk-slide-container"]/div/div[2]/img[2]').get_attribute('src') # 滑塊的圖片 地址 with open('Auth_Slide_Img/big_slide_img.jpg', 'wb') as f: f.write(requests.get(big_img_url).content) with open('Auth_Slide_Img/small_slide_img.jpg', 'wb') as f: f.write(requests.get(small_img_url).content) # 圖片轉為 灰度圖片 def img2gray(self, image): self.download_slide_auth_code_img() img_rgb = cv2.imread(image) # 讀入圖片 img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) # 轉灰度圖片 # cv2.imwrite(image, img_gray) # 儲存圖片,第一個引數:path, 第二個引數:儲存的圖片 return img_gray # 銳化邊緣 def canny_edge(self, image): self.img2gray(image) img = cv2.imread(image, 0) blur = cv2.GaussianBlur(img, (3, 3), 0) # 用高斯濾波處理原影象降噪 canny = cv2.Canny(blur, threshold1=200, threshold2=300) # 銳化圖片 # cv2.imwrite(image, canny) # 儲存圖片 # cv2.imshow('candy', can) # 彈出圖片 cv2.waitKey() cv2.destroyAllWindows() # 關閉視窗 return canny # 計算 2d 卷積 def convole2d(self, bg_array, fillter): bg_h, bg_w = bg_array.shape[:2] fillter_h, fillter_w = fillter.shape[:2] c_full = signal.convolve(bg_array, fillter, mode='full') kr, kc = fillter_h // 2, fillter_w // 2 c_same = c_full[ fillter_h - kr - 1: bg_h + fillter_h - kr - 1, fillter_w - kc - 1: bg_w + fillter_w - kr - 1, ] return c_same # 最終位置 def find_max_point(self, arrays, search_on_horizontal_center=False): max_point = 0 max_point_pos = None array_rows, arrays_cols = arrays.shape if search_on_horizontal_center: for col in range(arrays_cols): if arrays[array_rows // 2, col] > max_point: max_point = arrays[array_rows // 2, col] max_point_pos = col, array_rows // 2 else: for row in range(array_rows): for col in range(arrays_cols): if arrays[row, col] > max_point: max_point = arrays[row, col] max_point_pos = col, row return max_point_pos def main(self): self.input_user_pwd() canny1 = self.canny_edge('Auth_Slide_Img/big_slide_img.jpg') canny2 = self.canny_edge('Auth_Slide_Img/small_slide_img.jpg') convoled_after = self.convole2d(canny1, canny2) distance = self.find_max_point(convoled_after) print(distance) self.move_to_slide(distance[0]) return distance[0] def is_login(self): try: time.sleep(3) html = self.driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div[1]/button/i').click() print('login success!') self.driver.find_element_by_xpath( '/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[2]/div[2]/div[1]/div[2]/div[1]/span').click() time.sleep(1) self.driver.find_element_by_xpath( '/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[3]/div/div[1]/button/i').click() return True except: self.driver.close() print('login failed trying...') # self.is_login() return False def movement_search(self): self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div[1]/div/div[2]/div[3]/div/div[1]/input').send_keys('口紅') time.sleep(10) self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div[1]/div/div[2]/div[3]/i').send_keys(Keys.ENTER) time.sleep(6) self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div/div/div[1]/div[1]/div[1]/div[1]/div[2]/div[1]/div[1]').click() price1 = self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div/div[2]/div[2]/div[1]/div[1]/div[1]/div[1]/div/div[1]/div[1]/div/text()').extract() price2 = self.driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div/div[2]/div[2]/div[1]/div[2]/div[1]/div[1]/div/div[1]/div[1]/div/text()').extract() print(price1, price2) run = Pass_slide() run.main() login_result = run.is_login() print(login_result) run.movement_search()