geetest极验验证码使用

爬虫漫游指南:聊聊极验(Geetest) 上至政务类网站国家企业信用信息公示系统,下至娱乐类网站斗鱼战旗龙珠,都可以看到极验的身影。于是,如何绕过极验自然成为了许多爬虫小伙伴不得不面对的问题。本文就来聊一聊,爬虫遇到用极验的网站,该如何是好。 阅读详情

一、服务端代码 
1、去geetest官网注册并获取id和key 并引入新建geetestlib工具类

在github中clone出最新Demo项目,快速搭建本地应用:

git clone https://github.com/GeeTeam/gt-java-sdk.git 
前往 项目主页

引用SDK

将SDK中的目录下的 src/com 目录复制到你的项目中

import com.geetest.sdk.java.GeetestLib;

public class GeetestLib {

protected final String verName = "3.2.0";// SDK版本编号
protected final String sdkLang = "java";// SD的语言类型

protected final String apiUrl = "http://api.geetest.com"; //极验验证API URL
protected final String baseUrl = "api.geetest.com";

protected final String registerUrl = "/register.php"; //register url
protected final String validateUrl = "/validate.php"; //validate url

/**
 * 极验验证二次验证表单数据 chllenge
 */
public static final String FN_GEETEST_CHALLENGE = "geetest_challenge";

/**
 * 极验验证二次验证表单数据 validate
 */
public static final String FN_GEETEST_VALIDATE = "geetest_validate";

/**
 * 极验验证二次验证表单数据 seccode
 */
public static final String FN_GEETEST_SECCODE = "geetest_seccode";

/**
 * 公钥
 */
private String CAPTCHAID = "";

/**
 * 私钥
 */

private String PRIVATEKEY = "";

private String USERID = "";

private String RESPONSESTR = "";

/**
 * 调试开关,是否输出调试日志
 */
public boolean debugCode = true;

/**
 * 极验验证API服务状态Session Key
 */
public String gtServerStatusSessionKey = "gt_server_status";

/**
 * 带参数构造函数
 * 
 * @param captchaId
 * @param privateKey
 */
public GeetestLib(String captchaId, String privateKey) {
    this.CAPTCHAID = captchaId;
    this.PRIVATEKEY = privateKey;
}

/**
 * 获取本次验证初始化返回字符串
 * 
 * @return 初始化结果
 */
public String getResponseStr() {
    return RESPONSESTR;
}

public String getVersionInfo() {
    return verName;
}

/**
 * 预处理失败后的返回格式串
 * 
 * @return
 */
private String getFailPreProcessRes() {

    Long rnd1 = Math.round(Math.random() * 100);
    Long rnd2 = Math.round(Math.random() * 100);
    String md5Str1 = md5Encode(rnd1 + "");
    String md5Str2 = md5Encode(rnd2 + "");
    String challenge = md5Str1 + md5Str2.substring(0, 2);

    return String.format(
            "{\"success\":%s,\"gt\":\"%s\",\"challenge\":\"%s\"}", 0,
            this.CAPTCHAID, challenge);
}

/**
 * 预处理成功后的标准串
 * 
 */
private String getSuccessPreProcessRes(String challenge) {

    gtlog("challenge:" + challenge);
    return String.format(
            "{\"success\":%s,\"gt\":\"%s\",\"challenge\":\"%s\"}", 1,
            this.CAPTCHAID, challenge);
}

/**
 * 验证初始化预处理
 *
 * @return 1表示初始化成功,0表示初始化失败
 */
public int preProcess() {

    if (registerChallenge() != 1) {

        this.RESPONSESTR = this.getFailPreProcessRes();
        return 0;
    }

    return 1;

}

/**
 * 验证初始化预处理
 *
 * @param userid
 * @return 1表示初始化成功,0表示初始化失败
 */
public int preProcess(String userid){

    this.USERID = userid;
    return this.preProcess();
}

/**
 * 用captchaID进行注册,更新challenge
 * 
 * @return 1表示注册成功,0表示注册失败
 */
private int registerChallenge() {
    try {
        String GET_URL = apiUrl + registerUrl+"?gt=" + this.CAPTCHAID;
        if (this.USERID != ""){
            GET_URL = GET_URL + "&user_id=" + this.USERID;
            this.USERID = "";
        }
        gtlog("GET_URL:" + GET_URL);
        String result_str = readContentFromGet(GET_URL);
        gtlog("register_result:" + result_str);
        if (32 == result_str.length()) {

            this.RESPONSESTR = this.getSuccessPreProcessRes(this.md5Encode(result_str + this.PRIVATEKEY));

            return 1;
        } else {
            gtlog("gtServer register challenge failed");
            return 0;
        }
    } catch (Exception e) {
        gtlog("exception:register api");
    }
    return 0;
}

/**
 * 发送请求,获取服务器返回结果
 * 
 * @param getURL
 * @return 服务器返回结果
 * @throws IOException
 */
private String readContentFromGet(String getURL) throws IOException {

    URL getUrl = new URL(getURL);
    HttpURLConnection connection = (HttpURLConnection) getUrl
            .openConnection();

    connection.setConnectTimeout(2000);// 设置连接主机超时(单位:毫秒)
    connection.setReadTimeout(2000);// 设置从主机读取数据超时(单位:毫秒)

    // 建立与服务器的连接,并未发送数据
    connection.connect();

    // 发送数据到服务器并使用Reader读取返回的数据
    StringBuffer sBuffer = new StringBuffer();

    InputStream inStream = null;
    byte[] buf = new byte[1024];
    inStream = connection.getInputStream();
    for (int n; (n = inStream.read(buf)) != -1;) {
        sBuffer.append(new String(buf, 0, n, "UTF-8"));
    }
    inStream.close();
    connection.disconnect();// 断开连接

    return sBuffer.toString();
}


/**
 * 判断一个表单对象值是否为空
 * 
 * @param gtObj
 * @return
 */
protected boolean objIsEmpty(Object gtObj) {
    if (gtObj == null) {
        return true;
    }

    if (gtObj.toString().trim().length() == 0) {
        return true;
    }

    return false;
}

/**
 * 检查客户端的请求是否合法,三个只要有一个为空,则判断不合法
 * 
 * @param request
 * @return
 */
private boolean resquestIsLegal(String challenge, String validate, String seccode) {

    if (objIsEmpty(challenge)) {
        return false;
    }

    if (objIsEmpty(validate)) {
        return false;
    }

    if (objIsEmpty(seccode)) {
        return false;
    }

    return true;
}


/**
 * 服务正常的情况下使用的验证方式,向gt-server进行二次验证,获取验证结果
 * 
 * @param challenge
 * @param validate
 * @param seccode
 * @return 验证结果,1表示验证成功0表示验证失败
 */
public int enhencedValidateRequest(String challenge, String validate, String seccode) { 

    if (!resquestIsLegal(challenge, validate, seccode)) {
        return 0;
    }
    gtlog("request legitimate");

    String host = baseUrl;
    String path = validateUrl;
    int port = 80;
    String query = String.format("seccode=%s&sdk=%s", seccode,
            (this.sdkLang + "_" + this.verName));
    String response = "";

    if (this.USERID != ""){
        query = query + "&user_id=" + this.USERID;
        this.USERID = "";
    }
    gtlog(query);
    try {
        if (validate.length() <= 0) {
            return 0;
        }

        if (!checkResultByPrivate(challenge, validate)) {
            return 0;
        }
        gtlog("checkResultByPrivate");
        response = postValidate(host, path, query, port);

        gtlog("response: " + response);
    } catch (Exception e) {
        e.printStackTrace();
    }

    gtlog("md5: " + md5Encode(seccode));

    if (response.equals(md5Encode(seccode))) {
        return 1;
    } else {
        return 0;
    }
}

/**
 * 服务正常的情况下使用的验证方式,向gt-server进行二次验证,获取验证结果
 * 
 * @param challenge
 * @param validate
 * @param seccode
 * @param userid
 * @return 验证结果,1表示验证成功0表示验证失败
 */
public int enhencedValidateRequest(String challenge, String validate, String seccode, String userid) {  

    this.USERID = userid;
    return this.enhencedValidateRequest(challenge, validate, seccode);
}

/**
 * failback使用的验证方式
 * 
 * @param challenge
 * @param validate
 * @param seccode
 * @return 验证结果,1表示验证成功0表示验证失败
 */
public int failbackValidateRequest(String challenge, String validate, String seccode) {

    gtlog("in failback validate");

    if (!resquestIsLegal(challenge, validate, seccode)) {
        return 0;
    }
    gtlog("request legitimate");

    String[] validateStr = validate.split("_");
    String encodeAns = validateStr[0];
    String encodeFullBgImgIndex = validateStr[1];
    String encodeImgGrpIndex = validateStr[2];


    gtlog(String.format(
            "encode----challenge:%s--ans:%s,bg_idx:%s,grp_idx:%s",
            challenge, encodeAns, encodeFullBgImgIndex, encodeImgGrpIndex));

    int decodeAns = decodeResponse(challenge, encodeAns);
    int decodeFullBgImgIndex = decodeResponse(challenge, encodeFullBgImgIndex);
    int decodeImgGrpIndex = decodeResponse(challenge, encodeImgGrpIndex);

    gtlog(String.format("decode----ans:%s,bg_idx:%s,grp_idx:%s", decodeAns,
            decodeFullBgImgIndex, decodeImgGrpIndex));

    int validateResult = validateFailImage(decodeAns,decodeFullBgImgIndex, decodeImgGrpIndex);

    return validateResult;
}

/**
 *
 * @param ans
 * @param full_bg_index
 * @param img_grp_index
 * @return
 */
private int validateFailImage(int ans, int full_bg_index,
        int img_grp_index) {
    final int thread = 3;// 容差值

    String full_bg_name = md5Encode(full_bg_index + "").substring(0, 9);
    String bg_name = md5Encode(img_grp_index + "").substring(10, 19);

    String answer_decode = "";

    // 通过两个字符串奇数和偶数位拼接产生答案位
    for (int i = 0; i < 9; i++) {
        if (i % 2 == 0) {
            answer_decode += full_bg_name.charAt(i);
        } else if (i % 2 == 1) {
            answer_decode += bg_name.charAt(i);
        } else {
            gtlog("exception");
        }
    }

    String x_decode = answer_decode.substring(4, answer_decode.length());

    int x_int = Integer.valueOf(x_decode, 16);// 16 to 10

    int result = x_int % 200;
    if (result < 40) {
        result = 40;
    }

    if (Math.abs(ans - result) <= thread) {
        return 1;
    } else {
        return 0;
    }
}


/**
 * 解码随机参数
 * 
 * @param encodeStr
 * @param challenge
 * @return
 */
private int decodeResponse(String challenge, String string) {
    if (string.length() > 100) {
        return 0;
    }

    int[] shuzi = new int[] { 1, 2, 5, 10, 50 };
    String chongfu = "";
    HashMap<String, Integer> key = new HashMap<String, Integer>();
    int count = 0;

    for (int i = 0; i < challenge.length(); i++) {
        String item = challenge.charAt(i) + "";

        if (chongfu.contains(item) == true) {
            continue;
        } else {
            int value = shuzi[count % 5];
            chongfu += item;
            count++;
            key.put(item, value);
        }
    }

    int res = 0;

    for (int j = 0; j < string.length(); j++) {
        res += key.get(string.charAt(j) + "");
    }

    res = res - decodeRandBase(challenge);

    return res;

}

/**
 * 输入的两位的随机数字,解码出偏移量
 * 
 * @param randStr
 * @return
 */
private int decodeRandBase(String challenge) {

    String base = challenge.substring(32, 34);
    ArrayList<Integer> tempArray = new ArrayList<Integer>();

    for (int i = 0; i < base.length(); i++) {
        char tempChar = base.charAt(i);
        Integer tempAscii = (int) (tempChar);

        Integer result = (tempAscii > 57) ? (tempAscii - 87)
                : (tempAscii - 48);

        tempArray.add(result);
    }

    int decodeRes = tempArray.get(0) * 36 + tempArray.get(1);
    return decodeRes;

}

/**
 * 输出debug信息,需要开启debugCode
 * 
 * @param message
 */
public void gtlog(String message) {
    if (debugCode) {
        System.out.println("gtlog: " + message);
    }
}

protected boolean checkResultByPrivate(String challenge, String validate) {
    String encodeStr = md5Encode(PRIVATEKEY + "geetest" + challenge);
    return validate.equals(encodeStr);
}

/**
 * 貌似不是Post方式,后面重构时修改名字
 * 
 * @param host
 * @param path
 * @param data
 * @param port
 * @return
 * @throws Exception
 */
protected String postValidate(String host, String path, String data,
        int port) throws Exception {
    String response = "error";

    InetAddress addr = InetAddress.getByName(host);
    Socket socket = new Socket(addr, port);
    BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(
            socket.getOutputStream(), "UTF8"));
    wr.write("POST " + path + " HTTP/1.0\r\n");
    wr.write("Host: " + host + "\r\n");
    wr.write("Content-Type: application/x-www-form-urlencoded\r\n");
    wr.write("Content-Length: " + data.length() + "\r\n");
    wr.write("\r\n"); // 以空行作为分割

    // 发送数据
    wr.write(data);
    wr.flush();

    // 读取返回信息
    BufferedReader rd = new BufferedReader(new InputStreamReader(
            socket.getInputStream(), "UTF-8"));
    String line;
    while ((line = rd.readLine()) != null) {
        response = line;
    }
    wr.close();
    rd.close();
    socket.close();
    return response;
}


/**
 * md5 加密
 * 
 * @time 2014年7月10日 下午3:30:01
 * @param plainText
 * @return
 */
private String md5Encode(String plainText) {
    String re_md5 = new String();
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(plainText.getBytes());
        byte b[] = md.digest();
        int i;
        StringBuffer buf = new StringBuffer("");
        for (int offset = 0; offset < b.length; offset++) {
            i = b[offset];
            if (i < 0)
                i += 256;
            if (i < 16)
                buf.append("0");
            buf.append(Integer.toHexString(i));
        }

        re_md5 = buf.toString();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return re_md5;
}

} 
/********************************/ 
新建一个controller 并使用ajax实时校验 
* 从geetest网站获取的KEY和ID 
*/ 
private static final String CAPTCHA_ID = “自己申请”; 
private static final String CAPTCHA_KEY = “自己去官网免费申请”;

/**
 * @Title: verifyCaptchaCode
 * @Description: TODO(图片验证码二次验证返回结果)
 * @param @param request
 * @param @param response
 * @param @throws IOException 参数
 * @return void 返回类型
 * @throws
 */
@RequestMapping(value = "/verifyCaptchaCode")
@ResponseBody
public void verifyCaptchaCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
    GeetestLib gtSdk = new GeetestLib(CAPTCHA_ID, CAPTCHA_KEY);
    String challenge = request.getParameter(GeetestLib.FN_GEETEST_CHALLENGE);
    String validate = request.getParameter(GeetestLib.FN_GEETEST_VALIDATE);
    String seccode = request.getParameter(GeetestLib.FN_GEETEST_SECCODE);
    NotifyMsg msg = new NotifyMsg();
    /****************************/
    // 从session中获取gt-server状态
        int gt_server_status_code = (Integer)    request.getSession().getAttribute(gtSdk.gtServerStatusSessionKey);
    // 从session中获取userid
    String userid = SessionUtil.getAttr(request, "USERID").toString();
    int gtResult = 0;
    if (gt_server_status_code == 1) {
        // gt-server正常,向gt-server进行二次验证
        gtResult = gtSdk.enhencedValidateRequest(challenge, validate, seccode, userid);
        log.info("gtResult:" + gtResult);
    } else {
        // gt-server非正常情况下,进行failback模式验证
        log.info("failback:use your own server captcha validate");
        gtResult = gtSdk.failbackValidateRequest(challenge, validate, seccode);
        log.info("gtResult:" + gtResult);
    }
    if (gtResult != 1) {
        // 验证成功
        msg.init(1, "验证失败");
    }
    MethodUtil.toJsonMsg(response, msg.getKey(), msg.getMsg());
}

/**
 * @Title: startValidate
 * @Description: TODO(图片验证码初始验证返回输出验证码)
 * @param @param request
 * @param @param response 参数
 * @return void 返回类型
 * @throws
 */
@RequestMapping(value = "/startCaptcha")
@ResponseBody
public void startValidate(HttpServletRequest request, HttpServletResponse response) {
    GeetestLib gtSdk = new GeetestLib(CAPTCHA_ID, CAPTCHA_KEY);
    String resStr = "{}";
    // 自定义userid
    String userid = "CaptchaCode";
    // 进行验证预处理
    int gtServerStatus = gtSdk.preProcess(userid);
    // 将服务器状态设置到session中
    request.getSession().setAttribute(gtSdk.gtServerStatusSessionKey, gtServerStatus);
    // 将userid设置到session中
    SessionUtil.setAttr(request, "USERID", userid);
    resStr = gtSdk.getResponseStr();
    MethodUtil.toJsonPrint(response, resStr);
}

二、客户端代码 
注意,如果您的网站使用https,则只需要将引入极验库的地方换成https协议即可,不需要更改其它地方。例如SDK中的demo要使用https,则将以下代码:

更换成以下代码即可:

这里的话我们新建一个login.jsp 具体代码省略 
//新建一个显示验证码DIV 
//提交按钮并将BIND事件绑定到按钮中来 
下面是JS脚本放在最末尾

原文:https://blog.youkuaiyun.com/u010434697/article/details/51861205 
 

极验滑动验证码geetest.6.0.1破解 极验滑动验证码geetest.6.0.1破解目前在某小公司的大数据组实习,第二个爬虫练习就是工商的爬虫gsxt.gov.cn。与第一个爬虫练习不同,第一个的爬虫练习,验证码是图片,思路就是下载图片下来,人工输入验证码,提交参数,继续爬虫。而这个涉及到了滑动验证码,验证的参数并不是那么容易获取。于是站在前人的肩膀上,找到了以下超详细的教程,前面重复的东西就不写了,直接看大佬的文章吧。但是,该教程的验证 阅读详情

相关推荐

Django中使用极验Geetest滑动验证码过程解析

**一,环境部署 ** 1.创建一个django测试项目 二,文档部署 1.下载安装python对应的SDK 使用命令从Github导入完整项目:git clone https://github.com/GeeTeam/gt3-python-sdk.git 手动下载压缩包文件: https://github.com/GeeTeam/gt3-python-sdk/archive/master.zip 2.参数配置 修改请求参数(可选) 名称 说明 user_id 用户标识,若担心用户信息风

wx1871428的博客 559

python爬虫解决极验验证码问题

使用2captcha的服务解决登录时的极验验证码 爬虫在抓网站数据时,不可避免要和验证码做长久斗争。当然能绕过最好,但是总有绕不过的验证码,此时,对于简单的可以尝试绕过,有难度的对接打码平台。现在验证码多种多样,点选,滑动,英文字母组合等。所以要爬取一些网站的数据也越来越麻烦。   本篇就针对简书的依次点击文字的验证码进行破解 1、简书的验证技术采用的是极验提供的。 2、...

sunon_的博客 1万+

破解极验(geetest)滑动验证码

极验 目前大多数网站使用的验证方式,极验验证码主要分为点按、滑动、选字、选图、识字组词等方式。如下图所示: 点按 滑动 选字 选图 识字组词 当然这只是几种比较常见的验证码方式,还有旋转图片、找出一组图片中不是同一个人之类的,五花八门。。。 在这里只是简单讲解一下如何使用selenium破解极验的滑动验证码。 破解思路 找到验证码的图片 对比bg和fullbg两张图片,找到缺口位置 用selenium模拟人的行为拖动滑块 验证结果 具体步骤 在此之前先讲

易云云博客 2099

geetest极验验证-java使用笔记

业务场景 在系统业务中,需要想客户发送手机验证码,进行验证后,才能提交。但为了防止不正当的短信发送(攻击,恶意操作等),需要在发送短信前添加一个行为验证(这里使用的是 极验); 参考文档: 极验行为验证文档:https://docs.geetest.com/install/overview/start/ 极验demo:https://www.geetest.com/demo/ 步骤...

ent的博客 5253

Halcon-AOI外观缺陷检测系列

Halcon-AOI外观缺陷检测系列

Jumy_S的博客 1664

Ubuntu 22.04下Colmap带CUDA支持的编译安装全攻略(附显卡架构查询指南)

本文详细指导在Ubuntu 22.04系统上从源码编译安装支持CUDA加速的Colmap,解决了官方版本无GPU支持导致处理速度慢的问题。重点包括环境依赖准备、CUDA工具链配置、显卡计算能力查询以及完整的编译安装步骤,旨在帮助研究者和开发者高效部署高性能三维重建工具。

gold8的专栏 343

验证码的识别(极验验证码)

虽然有一定的错误率,比如,轨迹库不够丰富而导致取不到偏移量对应的轨迹,但是我们可以在接下来的程序里采用一种特殊的优化方式对其进行优化,可以保证每次登录100%成功。因此,一些人选择更艰难的方法,他们死磕JavaScript代码,破解每个请求中的加密参数,然后在程序中发送请求以获取正确响应。然而,极验为了增加破解的难度,对代码进行了大量的混淆操作,使得代码几乎无法被理解。对于其他非极验加密参数,如“loginPwd”、“jtSafeKey”、“token”等,这些都是XX官网自身的加密逻辑,破解难度不大。

asdsadgfd的博客 2568

Imputation Methods for scRNA Sequencing Data

越来越多的研究者使用单细胞RNA测序(scRNA-seq)技术来表征单细胞水平的转录图谱。他们用它来研究复杂组织的异质性、转录组动力学和未知生物的多样性。然而,在基因表达模式随机性的scRNA-seq数据中普遍存在许多技术和生物学上的噪音。这些数据通常具有高维、稀疏和大量“dropout”值的特点,并且受批处理效应的影响。scRNA-seq数据中大量的“dropout”值严重掩盖了基因之间的重要关系,阻碍了下游分析。因此,scRNA-seq数据dropout值的估算就显得尤为重要。

qq_34179307的博客 539

VUE中使用geetest滑动验证码

一,准备工作:服务端部署   下载文件gt.gs:  https://github.com/GeeTeam/gt3-python-sdk   需要说明的是这里的gt.js文件,它用于加载对应的验证JS库。   1.引入初始化函数     main.js import '../static/global/gt.js'   2.调用初始化函数进行初始化   api.js ...

weixin_30426957的博客 1620

利用GeoTools高效切割GeoTIFF为WebP瓦片:从配置到实战

本文详细介绍了如何利用GeoTools将GeoTIFF高效切割为WebP瓦片,从环境配置到实战技巧全面覆盖。通过对比WebP与PNG格式的优势,展示其在体积压缩和传输效率上的显著提升,并提供多线程切割、内存管理等性能优化方案,帮助开发者快速实现地理空间数据的Web地图服务部署。

agile9scrum的博客 812

NCBI Datasets CLI优化:解决基因组数据下载报错与速度问题

基因组数据下载是生物信息学分析的关键环节,其稳定性和效率直接影响研究进度。NCBI Datasets CLI作为官方命令行工具,常面临连接中断和下载速度慢两大痛点,这主要源于服务器连接限制和网络传输问题。通过自动重试机制和校验修复流程可提升稳定性,而连接复用与CDN加速等技术能显著提高下载效率。在植物基因组等大规模数据场景中,结合脱水模式和增量更新策略可减少70%传输量。本文以艾草基因组项目为例,展示如何通过并行下载和API优化将100个基因组的下载时间从18小时缩短至2小时,为生物信息学研究提供可靠的数据

weixin_29051245的博客 241

对极验geetest滑块验证码图片还原算法的研究

大部分开发者做爬虫时经常需要绕过该此类验证码进行下一步的爬虫,本文仅对极验geetest平台下的滑块验证码的图片还原进行分析与研究,试图找到打乱图片到正常图片之间的还原函数以及解析它还原算法的原理。

码农小易的博客 4498

【软件系统架构】系列六:系统工程

系统工程是一种跨学科方法论,用于分析、设计、集成和管理复杂系统的全生命周期。其核心特点包括系统性思维、全周期管理、跨学科协作和需求导向。主流采用V模型生命周期,涵盖需求分析、系统设计、实现、测试验证及运维退役等阶段。核心工作方法包括需求工程、系统建模、接口设计、风险管理等。系统工程与项目管理协同,分别侧重技术实现和进度资源管理。应用领域覆盖航天军工、智能制造、智慧城市等。未来将向AI融合、数字孪生、模型驱动工程等方向发展,为复杂系统开发提供系统化协作范式。

moton2017的博客 2256

破解极验(geetest)验证码

破解极验(geetest)验证码最近在搞爬虫的时候在好几个网站都碰到了一种叫做geetest的滑动条验证码,一直没有太好的办法只能在触发这个验证码后发个报警去手动处理一下。http://www.geetest.com/exp_embed是他们官网的样例。  后来研究了下觉得要破解这个验证码有这么几个问题:无法直接通过发送url请求来实现鼠标拖动的动作;实际的背景图片是乱的,并不是我们实际肉眼看到的...

半吊子python全栈 3万+

HTML爱心字母雨(完整代码)

HTML语言实现爱心字母雨的完整代码。

AIGC 2万+

第三篇:NVIDIA cuOpt Python API 详解:LP、QP、MILP 建模与求解,附核心术语名词解释

NVIDIA cuOpt是一款GPU加速的优化求解库,支持LP、QP、MILP和路径优化问题。本文详细介绍了其Python API使用方法,包括核心类Problem的变量定义、约束添加、目标设置和求解配置,并提供了术语解释。cuOpt通过GPU并行计算大幅提升大规模优化问题的求解效率,支持多种求解算法和参数配置,适用于需要高性能计算的优化场景。安装方式包含pip和Docker两种,验证安装后即可快速开始建模求解。

算法工程师 236

geetest极验空间推理验证码破解

从一开始gt和challenge的参数的获取,到后面w的生成,提交验证并获取最终的validate参数,就完成了整个该验证码的破解与识别。当然,嘴上说说还是比较简单,但是实际扣js代码并还原的过程还是比较痛苦的,这里就不一一赘述了。空间推理验证码是由sign提示和含有不同颜色,不同形状以及不同大小的物体组成的图片构成的,根据提示获取到指定的物体,并提交该物体的坐标即可。某验验证码3代,4代已经是老生常谈的问题了,本篇文章粗略的分析一波3代空间推理验证码识别与验证的整个过程。

flyskymood的博客 1531

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【2019.05】极验滑动验证码破解 geetest

【极验测试站】https://www.geetest.com/demo/slide-popup.html 滑动验证码如下图 破解滑动验证码一般都是得到验证码的原图和有滑块的图,这里我们抓包发现极验的原图和滑块图经过了一定的处理,比较难操作,所以我们可以通过截图的方式来处理。 原图 滑块图 结果展示 操作见代码,注释写的比较详细 #!/usr/bin/env python # encod...

ybsde博客 2602

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

geetest极验空间推理验证码破解与研究

geetest极验空间推理验证码破解

qq_41009507的博客 7671

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Laravel8集成 Geetest 极验验证码

简述 之前项目使用的行为验证一直是Geetest,但是最近升级了Laravel 框架8版本,发现之前的Geetest集成包无法使用了,安装composer 包 会报错说版本不支持8以上的版本,经过苦苦寻找发现了一个大佬集成的composer包,经测试可以使用。 地址:https://packagist.org/packages/zbrettonye/geetest建议阅读原项目的 README 文件。 下面简单介绍一下该工具包的使用。 注册极验账号 首先需要到极验网站注册账号,然后新建一...

DreamCoders 3627

Geetest极验验证码的使用

后端部署 1.首先从Github: gt3-python-sdk下载.zip文件 ,用于后台搭建 gt3-java-sdk-master\src\sdk\GeetestLib.java 这个文件相当java中的实体类 gt3-java-sdk-master\src\demo\demo1\GeetestConfig.java ,是geetest的配置文件,用来放我们在极验后台注册应用得到的capt...

Harden3的博客 2332

爬虫进阶教程:极验(GEETEST)验证码破解教程

原文链接及原作者:爬虫进阶教程:极验(GEETEST)验证码破解教程 | Jack Cui 一、前言 爬虫最大的敌人之一是什么?没错,验证码![Geetest]作为提供验证码服务的行家,市场占有率还是蛮高的。遇到Geetest提供的滑动验证码怎么破? 一种方法是分析它的js加密方法,通过大量抓包分析找到它的返回参数,直接自动生成需要的参数即可,这种方法工程量大一些,并且官方js脚本一升级,就得重...

weixin_33806509的博客 352
上一篇: 精通SpringBoot——第七篇:整合Redis实现缓存
下一篇: REDIS学习(3.2)spring boot 使用redis作为缓存
lhw_csd
博客等级 码龄9年 45粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值