Python 滑块验证码

看了滑块验证码(滑动验证码)相比图形验证码,破解难度如何?中《Python3网络爬虫开发实战》作者 崔庆才丨静觅 的一个回答,里面有详细介绍如何对抗滑块验证码,因此学习一下,对此进行记录。

正文

[1]流程


  • 利用 Python selenium 自动化测试工具 直接拟人行为来完成滑块验证码验证
  • 分析页面,找出滑块验证码的完整图片,缺口图片。
  • 对比原始的图片和带缺口的图片的像素,像素不同的地方就是缺口位置
  • 计算出滑块缺口的位置,得到所需要滑动的偏移量
  • 使用物理加速度位移公式计算出移动轨迹
  • 最后利用 Selenium 进行对滑块的拖拽


[2]分析页面

B站,是一个不错的学习网站,记得很久之前第一次碰到滑块验证码登录时候就是在B站看见的,所以拿它来练手。😃

哔哩哔哩登录页面

F12,打开开发者工具,找出登录框中有用的信息。

用户名输入:	id="login-username"
密码输入框:	id="login-passwd"
登录按钮:	 class="btn btn-login"
带有缺口的验证码图片: class="geetest_canvas_bg geetest_absolute"
需要滑动的验证码图片: class="geetest_canvas_slice geetest_absolute"
完整的验证码图片:    class="geetest_canvas_fullbg geetest_fade geetest_absolute"
滑块按钮:			class="geetest_slider_button"

[3]编写代码

导入库文件
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
import time
import random
from PIL import Image

USER_AGENT_LIST
USER_AGENT_LIST = [
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2226.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2225.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2224.3 Safari/537.36",
        "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 4.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36",
        "Mozilla/5.0 (X11; OpenBSD i386) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1944.0 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.3319.102 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2309.372 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2117.157 Safari/537.36",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1866.237 Safari/537.36",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/4E423F",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36 Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10",
        "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16",
        "Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14",
        "Mozilla/5.0 (Windows NT 6.0; rv:2.0) Gecko/20100101 Firefox/4.0 Opera 12.14",
        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0) Opera 12.14",
        "Opera/12.80 (Windows NT 5.1; U; en) Presto/2.10.289 Version/12.02",
        "Opera/9.80 (Windows NT 6.1; U; es-ES) Presto/2.9.181 Version/12.00",
        "Opera/9.80 (Windows NT 5.1; U; zh-sg) Presto/2.9.181 Version/12.00",
        "Opera/12.0(Windows NT 5.2;U;en)Presto/22.9.168 Version/12.00",
        "Opera/12.0(Windows NT 5.1;U;en)Presto/22.9.168 Version/12.00",
        "Mozilla/5.0 (Windows NT 5.1) Gecko/20100101 Firefox/14.0 Opera/12.0",
        "Opera/9.80 (Windows NT 6.1; WOW64; U; pt) Presto/2.10.229 Version/11.62",
        "Opera/9.80 (Windows NT 6.0; U; pl) Presto/2.10.229 Version/11.62",
        "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
        "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52",
        "Opera/9.80 (Windows NT 5.1; U; en) Presto/2.9.168 Version/11.51",
        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; de) Opera 11.51",
        "Opera/9.80 (X11; Linux x86_64; U; fr) Presto/2.9.168 Version/11.50",
        "Opera/9.80 (X11; Linux i686; U; hu) Presto/2.9.168 Version/11.50",
    ]
初始化函数
def init(self):
        """
        初始化变量
        :return:
        """
        global url, browser, username, password, wait

        url = 'https://passport.bilibili.com/login'

        path = r'G:\Python3\Scripts\chromedriver.exe'
        chrome_options = Options()
        #随机选择一个User_Agent
        user_agent = random.choice(USER_AGENT_LIST)
        #全屏
        chrome_options.add_argument('--start-maximized')
        chrome_options.add_argument('user-agent=%s'%user_agent)
        #开启开发者模式,可以进一步防止selenium被反爬虫识别
        chrome_options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors","enable-automation"])
        browser = webdriver.Chrome(executable_path=path, chrome_options=chrome_options)

        username = '用户名'

        password = '密码'
        wait = WebDriverWait(browser, 20)

global 关键字 定义了 url, browser, username, password, wait等全局变量,随后定义了chrome 的路径。

登录函数
def login(self):
        """
        输入帐号密码登录
        :return:
        """
        browser.get(url)

        user = wait.until(EC.presence_of_element_located((By.ID,'login-username')))

        passwd = wait.until(EC.presence_of_element_located((By.ID,'login-passwd')))

        user.send_keys(username)
        passwd.send_keys(password)
		#contains 就是包含,根据上面分析得知,登录按钮是的class是 btn btn-login 所以用XPATH 的contains函数就可以只选择其中之一。
        login_btn = wait.until(EC.presence_of_element_located((By.XPATH,"//a[contains(@class,'btn-login')]")))
        ran_time = random.random() * 2
        print("随机睡眠时间: ",ran_time)
        time.sleep(ran_time)

        login_btn.click()

等待用户名输入框和密码输入框对应的 ID 节点加载出来

获取这两个节点,用户名输入框 id="login-username",密码输入框 id="login-passwd"

调用 send_keys() 方法输入用户名和密码

获取登录按钮 class="btn btn-login"

随机产生一个数并将其扩大两倍作为暂停时间

最后调用 click() 方法实现登录按钮的点击


【4】验证码处理模块

验证码元素查找函数
def find_code(self):
        """
        查找 验证码图片
        :return:
        """
        
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python中的滑块验证码通常使用图像处理和模拟用户交互的方式来实现。以下是一个简单的示例代码,可以帮助你理解如何实现滑块验证码: ```python from PIL import Image from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains def get_slider_position(bg_image_path, slide_image_path): # 打开背景图和滑块图 bg_image = Image.open(bg_image_path) slide_image = Image.open(slide_image_path) # 获取滑块在背景图上的位置 for x in range(bg_image.width - slide_image.width): for y in range(bg_image.height - slide_image.height): is_match = True for i in range(slide_image.width): for j in range(slide_image.height): bg_pixel = bg_image.getpixel((x + i, y + j)) slide_pixel = slide_image.getpixel((i, j)) if abs(bg_pixel[0] - slide_pixel[0]) > 50 or \ abs(bg_pixel[1] - slide_pixel[1]) > 50 or \ abs(bg_pixel[2] - slide_pixel[2]) > 50: is_match = False break if not is_match: break if is_match: return x def slide_to_unlock(bg_image_path, slide_image_path): # 使用 selenium 打开网页,这里以 Chrome 为例 driver = webdriver.Chrome() driver.get("https://example.com") # 替换为需要验证的网页地址 # 定位到滑块元素 slider = driver.find_element_by_xpath("//div[@class='slider']") # 替换为滑块元素的 XPath # 获取滑块位置 slide_position = get_slider_position(bg_image_path, slide_image_path) # 模拟滑动操作 action = ActionChains(driver) action.click_and_hold(slider).perform() action.move_by_offset(slide_position, 0).perform() action.release().perform() slide_to_unlock("bg_image.png", "slide_image.png") # 替换为实际的背景图和滑块图路径 ``` 注意:上述代码仅为示例,实际应用中可能需要根据网页的具体情况进行适当的调整。另外,滑块验证码的具体实现方式可能因网站而异,因此你需要根据具体的网站来编写相应的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值