python selenium PIL破解滑动验证码

Letitia ·
更新时间:2024-09-21
· 723 次阅读

如今网站的的普滑动验证码一已经逐渐替代普通的验证码
这无疑加大了爬虫的工作量
滑动验证码可以显著优化用户体验,这在互联网时代是非常重要的。

通过这次实践我也学到了很多
今天我们以bilibili为例讲解破解滑动验证码的过程

需要用到的库 from PIL import ImageChops, Image from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import pyautogui from time import sleep import os 首先利用selenium自动填充用户名,密码并点击登录 driver = webdriver.Chrome() ac = ActionChains(driver) driver.implicitly_wait(3) driver.get('https://passport.bilibili.com/login') driver.maximize_window() # 输入账号和密码 input1 = driver.find_element_by_xpath('//div//input[@id="login-username"]').send_keys('18888888888') input2 = driver.find_element_by_xpath('//div//input[@id="login-passwd"]').send_keys('xxxxxxxx') driver.find_element_by_xpath('//div/a[@class="btn btn-login"]').click() # 点击登录按钮 sleep(1) 获取滑动验证码的背景图和带缺口的背景图 # 获取带缺口的图片 js = 'document.getElementsByClassName("geetest_canvas_slice")[0].className="geetest_canvas_slice geetest_absolute1"' driver.execute_script(js) img = driver.find_element_by_xpath('//*[@class="geetest_canvas_slice geetest_absolute1"]') ac.context_click(img).perform() pyautogui.typewrite(['enter', 'enter', 'enter'])

利用js修改class类命达到隐藏滑块就可以很轻松得到带缺口的背景图
在这里插入图片描述

# 获取完整的背景图片 js = 'document.getElementsByClassName("geetest_canvas_fullbg geetest_fade geetest_absolute")[0].style=""' driver.execute_script(js) img = driver.find_element_by_xpath('//*[@class="geetest_canvas_slice geetest_absolute1"]') ac.context_click(img).perform() pyautogui.typewrite(['enter', 'enter', 'enter'])

再通过删除style获取完整的背景图

在这里插入图片描述

# 恢复出带缺口的图片便于滑动时是观察(可选) js = 'document.getElementsByClassName("geetest_canvas_slice")[0].className="geetest_canvas_slice geetest_absolute"' driver.execute_script(js)

前面两部会删除滑块,不利于观察,加上这两句可以使原来的滑块恢复,即把类名改回原来的

对比两张图片找到缺口位置计算滑动多少像素 table = [] for i in range(256): if i 5: return w # 从下载中获取两张图片 def get_images(): bg = Image.open('C:/Users/yuaneuro/Downloads/下载.png') fullgb = Image.open('C:/Users/yuaneuro/Downloads/下载 (1).png') return bg, fullgb 最后编写主函数 def main(): bg_img, fullbg_img = get_images() gap = compute_gap(fullbg_img, bg_img) print(gap) # 寻找滑块的元素 slide = driver.find_element_by_xpath('//*[@class="geetest_slider_button"]') ac = ActionChains(driver) # 滑动操作(等待大佬更新滑动算法) ac.click_and_hold(slide).perform() ac.move_by_offset(gap - 10, 0.1).perform() # 平行移动鼠标 slide.click() ac.reset_actions() if __name__ == '__main__': main() os.remove('C:/Users/yuaneuro/Downloads/下载.png') os.remove('C:/Users/yuaneuro/Downloads/下载 (1).png')

这里滑动验证码已经更新,暂未找到合适有效的滑动轨迹的方法,暂时用最原始的替代,后续找到可以用的滑动轨迹会跟新!

完整代码 from PIL import ImageChops, Image from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains import pyautogui from time import sleep import os driver = webdriver.Chrome() ac = ActionChains(driver) driver.implicitly_wait(3) driver.get('https://passport.bilibili.com/login') driver.maximize_window() # 输入账号和密码 input1 = driver.find_element_by_xpath('//div//input[@id="login-username"]').send_keys('18888888888') input2 = driver.find_element_by_xpath('//div//input[@id="login-passwd"]').send_keys('xxxxxxxx') driver.find_element_by_xpath('//div/a[@class="btn btn-login"]').click() # 点击登录按钮 sleep(1) # 获取带缺口的图片 js = 'document.getElementsByClassName("geetest_canvas_slice")[0].className="geetest_canvas_slice geetest_absolute1"' driver.execute_script(js) img = driver.find_element_by_xpath('//*[@class="geetest_canvas_slice geetest_absolute1"]') ac.context_click(img).perform() pyautogui.typewrite(['enter', 'enter', 'enter']) # 获取完整的背景图片 js = 'document.getElementsByClassName("geetest_canvas_fullbg geetest_fade geetest_absolute")[0].style=""' driver.execute_script(js) img = driver.find_element_by_xpath('//*[@class="geetest_canvas_slice geetest_absolute1"]') ac.context_click(img).perform() pyautogui.typewrite(['enter', 'enter', 'enter']) # 恢复出带缺口的图片便于滑动时是观察(可选) js = 'document.getElementsByClassName("geetest_canvas_slice")[0].className="geetest_canvas_slice geetest_absolute"' driver.execute_script(js) # OpenCV识别滑动验证码的缺口 table = [] for i in range(256): if i 5: return w # 从下载中获取两张图片 def get_images(): bg = Image.open('C:/Users/yuaneuro/Downloads/下载.png') fullgb = Image.open('C:/Users/yuaneuro/Downloads/下载 (1).png') return bg, fullgb def main(): bg_img, fullbg_img = get_images() gap = compute_gap(fullbg_img, bg_img) print(gap) # 寻找滑块的元素 slide = driver.find_element_by_xpath('//*[@class="geetest_slider_button"]') ac = ActionChains(driver) # 滑动操作(等待大佬更新滑动算法) ac.click_and_hold(slide).perform() ac.move_by_offset(gap - 10, 0.1).perform() # 平行移动鼠标 slide.click() ac.reset_actions() if __name__ == '__main__': main() os.remove('C:/Users/yuaneuro/Downloads/下载.png') os.remove('C:/Users/yuaneuro/Downloads/下载 (1).png')
作者:yuaneuro



滑动验证码 滑动验证 验证码 selenium Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号