《【Python爬虫】DrissionPage+验证码开放平台,挑战三十行代码全程通过极验行为验证码–九宫格》
行为验证码识别是一个涉及图像处理和自动化技术的复杂问题,通常用于研究或合法场景(如自动化测试)。善于利用各种工具可以提升我们的开发效率,这里以《极验四代行为验证码–九宫格》为例子,挑战三十行代码全程通过行为验证码,以下是技术实现的基本思路和注意事项。


1. 目标网站

  • url地址:aHR0cHM6Ly9ndDQuZ2VldGVzdC5jb20v

2. 准备基本工具

  • Python 安装

  • 这里作者使用的是 python3.10 版本,咋安装这也要说么???

  • DrissionPage 安装

  • DrissionPage® 是一个基于 Python 的网页自动化工具。

  • 既能控制浏览器,也能收发数据包,还能把两者合而为一。

  • 可兼顾浏览器自动化的便利性和 requests 的高效率。

  • 功能强大,语法简洁优雅,代码量少,对新手友好。

  • DrissionPage安装和使用教程具体参考:https://github.com/g1879/DrissionPage,这里不概述

  • 验证码开放平台

  • 使用自己熟悉的验证码平台,一定要稳定,高准确率,验证码种类齐全!!!

  • 这里推荐平台:DecodeCaptcha.com
    请添加图片描述


2. 技术实现步骤

步骤1:获取验证码图像
  • 进入目标网站–配置–九宫格验证–点击按钮开始验证,出现验证码图片
  • 使用自动化工具 DrissionPage 截取网页中的背景图和标题图。
  • 示例代码(Python + DrissionPage):
    # 获取背景图像
    bg_ele = tab.ele('@class:geetest_nine')
    bg_base64 = bg_ele.get_screenshot(as_base64='jpg')  # 返回 base64 格式的字符串
    
    # 获取标题图像
    # 使用方案一,直接截图, 标题图太小,图像失真,无法用于识别,被迫放弃
    # title_base64 = tab.ele('@class:geetest_ques_back').get_screenshot(as_base64='jpg')  # 返回 base64 格式的字符串
    
    # 使用方案二,直接获取图像链接, 请求图像二进制再编码为 base64
    title_url = tab.ele('@class:geetest_ques_back').ele('tag:img').attr('src')
    title_bytes = requests.get(title_url).content
    title_base64 = base64.b64encode(title_bytes).decode('utf-8')
    
步骤2:图像识别
  • 图像识别可以使用深度学习框架训练 九宫格 识别模型。这里追求开发效率所以使用验证码开放平台,不需要我们自己折腾。
  • 注册 DecodeCaptcha.com – 获取API密钥:MY_API_KEY
  • 选择模型 【3140205 - 1402类 - 九宫格点选】, image_id=3140205
  • 示例代码:
    # 选择模型 【3140205 - 1402类 - 九宫格点选】, image_id=3140205
    url = "https://api.decodecaptcha.com/images?key=MY_API_KEY&image_id=3140205"
    payload = json.dumps({
        "image": bg_base64,
        "title": title_base64
    })
    # POST请求方式,上传背景图和标题图
    response = requests.post(url, headers={'Content-Type': 'application/json'}, data=payload)
    json_data = response.json() # 返回识别结果
    
步骤3:模拟点击操作
  • 示例代码(模拟点击):
    # 依次点击点击背景图元素
    for i in json_data['data']['answer']:
        # 提取中心坐标
        center = json_data['data']['boxs'][str(i)]['center']
        x, y = center
        # 偏移量相对于背景图元素左上角坐标,由于网站前端会根据浏览器窗口大小改变背景图元素大小,所以必须设置窗口大小 (1920, 1080)
        bg_ele.click.at(offset_x=x, offset_y=y)
    

在这里插入图片描述

4. 通过验证并登录

  • 示例代码:
    time.sleep(1) # 等待验证码加载完成
    
    # 登录
    tab.ele('@text()=登录').click()
    
    # 是否成功?
    # 浏览器弹窗提示:success,代表成功通过验证并实现登录
    
    # 此方法用于关闭标签页
    # tab.close()
    

在这里插入图片描述

4. 完整代码示例

  • 示例代码:
    # 导入依赖
    import time
    import json
    import base64
    import requests
    from DrissionPage import Chromium
    
    browser = Chromium() # 连接浏览器
    
    tab = browser.latest_tab # 获取标签页对象
    
    tab.set.window.size(1920, 1080) # 设置窗口大小
    
    tab.get('https://gt4.geetest.com/') # 访问网页
    
    tab.ele('@text()=配置').click() # 点击第一个文本为“配置”的元素
    
    tab.ele('@text()=九宫格验证').click() # 点击第一个文本为“九宫格验证”的元素
    
    tab.ele('@aria-label=点击按钮开始验证').click()
    
    time.sleep(5) # 等待验证码加载完成
    
    # 获取背景图像
    bg_ele = tab.ele('@class:geetest_nine')
    bg_base64 = bg_ele.get_screenshot(as_base64='jpg')  # 返回 base64 格式的字符串
    
    # 获取标题图像
    # 使用方案一,直接截图, 标题图太小,图像失真,无法用于识别,被迫放弃
    # title_base64 = tab.ele('@class:geetest_ques_back').get_screenshot(as_base64='jpg')  # 返回 base64 格式的字符串
    
    # 使用方案二,直接获取图像链接, 请求图像二进制再编码为 base64
    title_url = tab.ele('@class:geetest_ques_back').ele('tag:img').attr('src')
    title_bytes = requests.get(title_url).content
    title_base64 = base64.b64encode(title_bytes).decode('utf-8')
    
    # 注册 decodecaptcha.com 验证码开放平台 -- 获取API密钥:MY_API_KEY
    # 选择模型 【3140205 - 1402类 - 九宫格点选】, image_id=3140205
    url = "https://api.decodecaptcha.com/images?key=MY_API_KEY&image_id=3140205"
    payload = json.dumps({
        "image": bg_base64,
        "title": title_base64
    })
    # POST请求方式,上传背景图和标题图
    response = requests.post(url, headers={'Content-Type': 'application/json'}, data=payload)
    json_data = response.json() # 返回识别结果
    
    # 依次点击点击背景图元素
    for i in json_data['data']['answer']:
        # 提取中心坐标
        center = json_data['data']['boxs'][str(i)]['center']
        x, y = center
        # 偏移量相对于背景图元素左上角坐标,由于网站前端会根据浏览器窗口大小改变背景图元素大小,所以必须设置窗口大小 (1920, 1080)
        bg_ele.click.at(offset_x=x, offset_y=y)
    
    time.sleep(1) # 等待验证码加载完成
    
    # 登录
    tab.ele('@text()=登录').click()
    
    # 是否成功?
    # 浏览器弹窗提示:success,代表成功通过验证并实现登录
    
    # 此方法用于关闭标签页
    # tab.close()
    
    
    # 3140205 - 1402类 - 九宫格点选
    # 返回识别结果 - 参考例子
    # {
    #     "msg": "",
    #     "data": {
    #         "boxs": {
    #             "0": {
    #                 "id": 0,
    #                 "box": [
    #                     0,
    #                     0,
    #                     100,
    #                     87
    #                 ],
    #                 "center": [
    #                     50,
    #                     43
    #                 ]
    #             },
    #             "1": {
    #                 "id": 1,
    #                 "box": [
    #                     100,
    #                     0,
    #                     200,
    #                     87
    #                 ],
    #                 "center": [
    #                     150,
    #                     43
    #                 ]
    #             },
    #             "2": {
    #                 "id": 2,
    #                 "box": [
    #                     200,
    #                     0,
    #                     300,
    #                     87
    #                 ],
    #                 "center": [
    #                     250,
    #                     43
    #                 ]
    #             },
    #             "3": {
    #                 "id": 3,
    #                 "box": [
    #                     0,
    #                     87,
    #                     100,
    #                     174
    #                 ],
    #                 "center": [
    #                     50,
    #                     130
    #                 ]
    #             },
    #             "4": {
    #                 "id": 4,
    #                 "box": [
    #                     100,
    #                     87,
    #                     200,
    #                     174
    #                 ],
    #                 "center": [
    #                     150,
    #                     130
    #                 ]
    #             },
    #             "5": {
    #                 "id": 5,
    #                 "box": [
    #                     200,
    #                     87,
    #                     300,
    #                     174
    #                 ],
    #                 "center": [
    #                     250,
    #                     130
    #                 ]
    #             },
    #             "6": {
    #                 "id": 6,
    #                 "box": [
    #                     0,
    #                     174,
    #                     100,
    #                     261
    #                 ],
    #                 "center": [
    #                     50,
    #                     217
    #                 ]
    #             },
    #             "7": {
    #                 "id": 7,
    #                 "box": [
    #                     100,
    #                     174,
    #                     200,
    #                     261
    #                 ],
    #                 "center": [
    #                     150,
    #                     217
    #                 ]
    #             },
    #             "8": {
    #                 "id": 8,
    #                 "box": [
    #                     200,
    #                     174,
    #                     300,
    #                     261
    #                 ],
    #                 "center": [
    #                     250,
    #                     217
    #                 ]
    #             }
    #         },
    #         "answer": [
    #             2,
    #             4,
    #             6
    #         ]
    #     },
    #     "image_id": 3140204
    # }
    

5. 注意事项

  • 合法使用:本文只用于学习交流与研究参考,禁止用于非法用途,禁止用于攻击他人系统。不可违反网站服务条款。


如果需要进一步探讨具体技术细节或开展业务遇到阻力:
https://github.com/decodecaptcha

更多推荐