1. 程式人生 > 實用技巧 >爬蟲-selenium實現驗證碼自動登入(14)

爬蟲-selenium實現驗證碼自動登入(14)

import time
from io import BytesIO
import random

import requests
from selenium import webdriver
from selenium.webdriver import ActionChains
from PIL import Image

url = "https://www.douban.com/"
browser = webdriver.Chrome(executable_path="E:/爬蟲0基礎入門/chromedriver_win32/chromedriver.exe")


#2. 點選元素顯示出有缺口的圖片並下載
#3. 對比兩張圖片找出缺口的移動畫素 #4. 拖動元素 url = "https://passport.bilibili.com/login" def compare_pixel(image1, image2, i, j): #判斷兩個畫素是否相同 pixel1 = image1.load()[i, j] pixel2 = image2.load()[i, j] threshold = 60 if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and
abs(pixel1[2] - pixel2[2]) < threshold: return True return False def crop_image(image_file_name): #截圖驗證碼圖片 #定位某個元素在瀏覽器中的位置 time.sleep(2) img = browser.find_element_by_xpath("//*[@class='gt_box']") location = img.location print("圖片的位置", location) size = img.size top, buttom, left, right
= location["y"], location["y"]+size["height"], location["x"], location['x'] + size["width"] print("驗證碼位置", left,top, right, buttom) screenshot = browser.get_screenshot_as_png() screenshot = Image.open(BytesIO(screenshot)) captcha = screenshot.crop((int(left),int(top), int(right), int(buttom))) captcha.save(image_file_name) return captcha def login(): username = "17716131585" password = "123456" browser.get(url) browser.maximize_window() #很重要!! username_ele = browser.find_element_by_xpath("//input[@id='login-username']") password_ele = browser.find_element_by_xpath("//input[@id='login-passwd']") username_ele.send_keys(username) password_ele.send_keys(password) # 1. 滑鼠移動到正確的元素上,顯示出沒有缺口的圖片並下載 time.sleep(2) slider = browser.find_element_by_xpath("//div[@class='gt_slider_knob gt_show']") ActionChains(browser).move_to_element(slider).perform() #如果擷取圖片 image1 = crop_image("captcha1.png") #獲取缺口圖片 ActionChains(browser).click_and_hold(slider).perform() time.sleep(1) image2 = crop_image("captcha2.png") #獲取缺口圖片的位置 left = 60 has_find = False for i in range(left, image1.size[0]): if has_find: break for j in range(image1.size[1]): if not compare_pixel(image1, image2, i, j): left = i has_find = True break left -= 6 print(left) #拖動圖片 # 根據偏移量獲取移動軌跡 # 一開始加速,然後減速,生長曲線,且加入點隨機變動 # 移動軌跡 track = [] # 當前位移 current = 0 # 減速閾值 mid = left * 3 / 4 # 間隔時間 t = 0.1 v = 0 while current < left: if current < mid: a = random.randint(2, 3) else: a = - random.randint(6, 7) v0 = v # 當前速度 v = v0 + a * t # 移動距離 move = v0 * t + 1 / 2 * a * t * t # 當前位移 current += move track.append(round(move)) # ActionChains(browser).click_and_hold(slider).perform() for x in track: ActionChains(browser).move_by_offset(xoffset=x, yoffset=0).perform() time.sleep(0.5) ActionChains(browser).release().perform() time.sleep(3) try: browser.find_element_by_xpath("//span[contains(text(), '驗證通過')]") return True except Exception as e: if login(): return True if __name__ == "__main__": login()