如今网站的的普滑动验证码一已经逐渐替代普通的验证码
这无疑加大了爬虫的工作量
滑动验证码可以显著优化用户体验,这在互联网时代是非常重要的。
通过这次实践我也学到了很多
今天我们以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')