极验验证目录

  • 一、样例
  • 二、注册账号
  • 三、获取ID
  • 四、极验官方文档(参考)
  • 五、SpringBoot集成极验
    • 5.1、maven依赖(可能有些需要自己去导,个人的包依赖太多不好全部放上来,核心就这两个)
    • 5.2、yml配置文件
    • 5.3、util类(读本地ip)
    • 5.4、读取配置类
    • 5.5、获取极验的第一次数据包
      • 5.5.1、在资源服务器里面放行路径
      • 5.5.2、添加控制器 GeetestController
      • 5.5.3、在gateway网关里面添加 CorsConfig

一、样例

二、注册账号

极验验证官网

在表单里面填写真实信息,客服会在 24h 联系你进行审核,审核通过后,会发送这样的邮件到你的邮箱。

点击邮箱里面提供的注册地址即可完成注册。 注册成功后,进行登录:

三、获取ID



填写基本信息:

创建成功后:

点击 ID:

点击查看部署指引:

都勾选成功后,点击确认:

获取到了 ID 和 KEY:

记录 ID 和 KEY:

ID               上面获得到的id
KEY             上面获取到的value

四、极验官方文档(参考)

文档地址:
https://docs.geetest.com/sensebot/start/
服务端:
https://docs.geetest.com/sensebot/deploy/server/java#%E9%85%8D%E7%BD %AE%E5%AF%86%E9%92%A5
Web 端:
https://docs.geetest.com/sensebot/deploy/client/web

五、SpringBoot集成极验

5.1、maven依赖(可能有些需要自己去导,个人的包依赖太多不好全部放上来,核心就这两个)

   <!--json的依赖--><dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>20171018</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency>

5.2、yml配置文件

spring:redis:host: redis-server      #自己redis的ip,此处我做了ip映射port: 6380password: 123456
geetest:geetest-id: 上面获得到的idgeetest-key: 上面获取到的value

5.3、util类(读本地ip)

package com.zhz.util;import javax.servlet.http.HttpServletRequest;/*** 获取本地ip地址*/
public class IpUtil {public static String getIpAddr(HttpServletRequest request) {String ip = request.getHeader("X-Forwarded-For");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_CLIENT_IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_X_FORWARDED_FOR");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("HTTP_X_CONNECTING_IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}} else if (ip.length() > 15) {String[] ips = ip.split(",");for (int index = 0; index < ips.length; index++) {String strIp = (String) ips[index];if (!("unknown".equalsIgnoreCase(strIp))) {ip = strIp;break;}}}return ip;}
}
/*** @(#)Result.JAVA, 2020年05月22日.* <p>* Copyright 2020 GEETEST, Inc. All rights reserved.* GEETEST PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*/
package com.zhz.geetest;import org.json.JSONObject;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;/*** sdk lib包,核心逻辑。*/
public class GeetestLib {/*** 公钥*/private String geetest_id;/*** 私钥*/private String geetest_key;/*** 返回数据的封装对象*/private GeetestLibResult libResult;/*** 调试开关,是否输出调试日志*/private static final boolean IS_DEBUG = true;private static final String API_URL = "http://api.geetest.com";private static final String REGISTER_URL = "/register.php";private static final String VALIDATE_URL = "/validate.php";private static final String JSON_FORMAT = "1";private static final boolean NEW_CAPTCHA = true;private static final int HTTP_TIMEOUT_DEFAULT = 5000; // 单位:毫秒public static final String VERSION = "jave-servlet:3.1.0";/*** 极验二次验证表单传参字段 chllenge*/public static final String GEETEST_CHALLENGE = "geetest_challenge";/*** 极验二次验证表单传参字段 validate*/public static final String GEETEST_VALIDATE = "geetest_validate";/*** 极验二次验证表单传参字段 seccode*/public static final String GEETEST_SECCODE = "geetest_seccode";/*** 极验验证API服务状态Session Key*/public static final String GEETEST_SERVER_STATUS_SESSION_KEY = "gt_server_status";/*** 极验证里面的user*/public static final String GEETEST_SERVER_USER_KEY = "gt_server_user";public GeetestLib(String geetest_id, String geetest_key) {this.geetest_id = geetest_id;this.geetest_key = geetest_key;this.libResult = new GeetestLibResult();}public void gtlog(String message) {if (this.IS_DEBUG) {System.out.println("gtlog: " + message);}}/*** 验证初始化*/public GeetestLibResult register(String digestmod, Map<String, String> paramMap) {this.gtlog(String.format("register(): 开始验证初始化, digestmod=%s.", digestmod));String origin_challenge = this.requestRegister(paramMap);this.buildRegisterResult(origin_challenge, digestmod);this.gtlog(String.format("register(): 验证初始化, lib包返回信息=%s.", this.libResult));return this.libResult;}/*** 向极验发送验证初始化的请求,GET方式*/private String requestRegister(Map<String, String> paramMap) {paramMap.put("gt", this.geetest_id);paramMap.put("json_format", this.JSON_FORMAT);paramMap.put("sdk", this.VERSION);String register_url = this.API_URL + this.REGISTER_URL;this.gtlog(String.format("requestRegister(): 验证初始化, 向极验发送请求, url=%s, params=%s.", register_url, paramMap));String origin_challenge = null;try {String resBody = this.httpGet(register_url, paramMap);this.gtlog(String.format("requestRegister(): 验证初始化, 与极验网络交互正常, 返回body=%s.", resBody));JSONObject jsonObject = new JSONObject(resBody);origin_challenge = jsonObject.getString("challenge");} catch (Exception e) {this.gtlog("requestRegister(): 验证初始化, 请求异常,后续流程走宕机模式, " + e.toString());origin_challenge = "";}return origin_challenge;}/*** 构建验证初始化接口返回数据*/private void buildRegisterResult(String origin_challenge, String digestmod) {// origin_challenge为空或者值为0代表失败if (origin_challenge == null || origin_challenge.isEmpty() || "0".equals(origin_challenge)) {// 本地随机生成32位字符串String challenge = UUID.randomUUID().toString().replaceAll("-", "");JSONObject jsonObject = new JSONObject();jsonObject.put("success", 0);jsonObject.put("gt", this.geetest_id);jsonObject.put("challenge", challenge);jsonObject.put("new_captcha", this.NEW_CAPTCHA);this.libResult.setAll(0, jsonObject.toString(), "请求极验register接口失败,后续流程走宕机模式");} else {String challenge = null;if ("md5".equals(digestmod)) {challenge = this.md5_encode(origin_challenge + this.geetest_key);} else if ("sha256".equals(digestmod)) {challenge = this.sha256_encode(origin_challenge + this.geetest_key);} else if ("hmac-sha256".equals(digestmod)) {challenge = this.hmac_sha256_encode(origin_challenge, this.geetest_key);} else {challenge = this.md5_encode(origin_challenge + this.geetest_key);}JSONObject jsonObject = new JSONObject();jsonObject.put("success", 1);jsonObject.put("gt", this.geetest_id);jsonObject.put("challenge", challenge);jsonObject.put("new_captcha", this.NEW_CAPTCHA);this.libResult.setAll(1, jsonObject.toString(), "");}}/*** 正常流程下(即验证初始化成功),二次验证*/public GeetestLibResult successValidate(String challenge, String validate, String seccode, Map<String, String> paramMap) {this.gtlog(String.format("successValidate(): 开始二次验证 正常模式, challenge=%s, validate=%s, seccode=%s.", challenge, validate, seccode));if (!this.checkParam(challenge, validate, seccode)) {this.libResult.setAll(0, "", "正常模式,本地校验,参数challenge、validate、seccode不可为空");} else {String response_seccode = this.requestValidate(challenge, validate, seccode, paramMap);if (response_seccode == null || response_seccode.isEmpty()) {this.libResult.setAll(0, "", "请求极验validate接口失败");} else if ("false".equals(response_seccode)) {this.libResult.setAll(0, "", "极验二次验证不通过");} else {this.libResult.setAll(1, "", "");}}this.gtlog(String.format("successValidate(): 二次验证 正常模式, lib包返回信息=%s.", this.libResult));return this.libResult;}/*** 异常流程下(即验证初始化失败,宕机模式),二次验证* 注意:由于是宕机模式,初衷是保证验证业务不会中断正常业务,所以此处只作简单的参数校验,可自行设计逻辑。*/public GeetestLibResult failValidate(String challenge, String validate, String seccode) {this.gtlog(String.format("failValidate(): 开始二次验证 宕机模式, challenge=%s, validate=%s, seccode=%s.", challenge, validate, seccode));if (!this.checkParam(challenge, validate, seccode)) {this.libResult.setAll(0, "", "宕机模式,本地校验,参数challenge、validate、seccode不可为空.");} else {this.libResult.setAll(1, "", "");}this.gtlog(String.format("failValidate(): 二次验证 宕机模式, lib包返回信息=%s.", this.libResult));return this.libResult;}/*** 向极验发送二次验证的请求,POST方式*/private String requestValidate(String challenge, String validate, String seccode, Map<String, String> paramMap) {paramMap.put("seccode", seccode);paramMap.put("json_format", this.JSON_FORMAT);paramMap.put("challenge", challenge);paramMap.put("sdk", this.VERSION);paramMap.put("captchaid", this.geetest_id);String validate_url = this.API_URL + this.VALIDATE_URL;this.gtlog(String.format("requestValidate(): 二次验证 正常模式, 向极验发送请求, url=%s, params=%s.", validate_url, paramMap));String response_seccode = null;try {String resBody = this.httpPost(validate_url, paramMap);this.gtlog(String.format("requestValidate(): 二次验证 正常模式, 与极验网络交互正常, 返回body=%s.", resBody));JSONObject jsonObject = new JSONObject(resBody);response_seccode = jsonObject.getString("seccode");} catch (Exception e) {this.gtlog("requestValidate(): 二次验证 正常模式, 请求异常, " + e.toString());response_seccode = "";}return response_seccode;}/*** 校验二次验证的三个参数,校验通过返回true,校验失败返回false*/private boolean checkParam(String challenge, String validate, String seccode) {return !(challenge == null || challenge.trim().isEmpty() || validate == null || validate.trim().isEmpty() || seccode == null || seccode.trim().isEmpty());}/*** 发送GET请求,获取服务器返回结果*/private String httpGet(String url, Map<String, String> paramMap) throws Exception {HttpURLConnection connection = null;InputStream inStream = null;try {Iterator<String> it = paramMap.keySet().iterator();StringBuilder paramStr = new StringBuilder();while (it.hasNext()) {String key = it.next();if (key == null || key.isEmpty() || paramMap.get(key) == null || paramMap.get(key).isEmpty()) {continue;}paramStr.append("&").append(URLEncoder.encode(key, "utf-8")).append("=").append(URLEncoder.encode(paramMap.get(key), "utf-8"));}if (paramStr.length() != 0) {paramStr.replace(0, 1, "?");}url += paramStr.toString();URL getUrl = new URL(url);connection = (HttpURLConnection) getUrl.openConnection();connection.setConnectTimeout(this.HTTP_TIMEOUT_DEFAULT); // 设置连接主机超时(单位:毫秒)connection.setReadTimeout(this.HTTP_TIMEOUT_DEFAULT); // 设置从主机读取数据超时(单位:毫秒)connection.connect();if (connection.getResponseCode() == 200) {StringBuilder sb = new StringBuilder();byte[] buf = new byte[1024];inStream = connection.getInputStream();for (int n; (n = inStream.read(buf)) != -1; ) {sb.append(new String(buf, 0, n, "UTF-8"));}return sb.toString();}return "";} catch (Exception e) {throw e;} finally {if (inStream != null) {inStream.close();}if (connection != null) {connection.disconnect();}}}/*** 发送POST请求,获取服务器返回结果*/private String httpPost(String url, Map<String, String> paramMap) throws Exception {HttpURLConnection connection = null;InputStream inStream = null;try {Iterator<String> it = paramMap.keySet().iterator();StringBuilder paramStr = new StringBuilder();while (it.hasNext()) {String key = it.next();if (key == null || key.isEmpty() || paramMap.get(key) == null || paramMap.get(key).isEmpty()) {continue;}paramStr.append("&").append(URLEncoder.encode(key, "utf-8")).append("=").append(URLEncoder.encode(paramMap.get(key), "utf-8"));}if (paramStr.length() != 0) {paramStr.replace(0, 1, "");}URL postUrl = new URL(url);connection = (HttpURLConnection) postUrl.openConnection();connection.setConnectTimeout(this.HTTP_TIMEOUT_DEFAULT);// 设置连接主机超时(单位:毫秒)connection.setReadTimeout(this.HTTP_TIMEOUT_DEFAULT);// 设置从主机读取数据超时(单位:毫秒)connection.setRequestMethod("POST");connection.setDoInput(true);connection.setDoOutput(true);connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");connection.connect();OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream(), "utf-8");outputStreamWriter.write(paramStr.toString());outputStreamWriter.flush();outputStreamWriter.close();if (connection.getResponseCode() == 200) {StringBuilder sb = new StringBuilder();byte[] buf = new byte[1024];inStream = connection.getInputStream();for (int n; (n = inStream.read(buf)) != -1; ) {sb.append(new String(buf, 0, n, "UTF-8"));}inStream.close();connection.disconnect();return sb.toString();}return "";} catch (Exception e) {throw e;} finally {if (inStream != null) {inStream.close();}if (connection != null) {connection.disconnect();}}}/*** md5 加密*/private String md5_encode(String value) {String re_md5 = new String();try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(value.getBytes());byte b[] = md.digest();int i;StringBuilder sb = new StringBuilder("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0)i += 256;if (i < 16)sb.append("0");sb.append(Integer.toHexString(i));}re_md5 = sb.toString();} catch (Exception e) {this.gtlog("md5_encode(): 发生异常, " + e.toString());}return re_md5;}/*** sha256加密*/public String sha256_encode(String value) {MessageDigest messageDigest;String encodeStr = new String();try {messageDigest = MessageDigest.getInstance("SHA-256");messageDigest.update(value.getBytes("UTF-8"));encodeStr = byte2Hex(messageDigest.digest());} catch (Exception e) {this.gtlog("sha256_encode(): 发生异常, " + e.toString());}return encodeStr;}/*** 将byte转为16进制*/private static String byte2Hex(byte[] bytes) {StringBuilder sb = new StringBuilder();String temp = null;for (int i = 0; i < bytes.length; i++) {temp = Integer.toHexString(bytes[i] & 0xFF);if (temp.length() == 1) {// 得到一位的进行补0操作sb.append("0");}sb.append(temp);}return sb.toString();}/*** hmac-sha256 加密*/private String hmac_sha256_encode(String value, String key) {String encodeStr = new String();try {Mac sha256_HMAC = Mac.getInstance("HmacSHA256");SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");sha256_HMAC.init(secret_key);byte[] array = sha256_HMAC.doFinal(value.getBytes("UTF-8"));StringBuilder sb = new StringBuilder();for (byte item : array) {sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));}encodeStr = sb.toString();} catch (Exception e) {this.gtlog("hmac_sha256_encode(): 发生异常, " + e.toString());}return encodeStr;}}

5.4、读取配置类

package com.zhz.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** @author :zhz* @date :Created in 2021/01/02* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description: 极验验证的ID和Key配置**/
@Data
@ConfigurationProperties(prefix = "geetest")
public class GeetestProperties {/*** 极验的 ID*/private String geetestId;/*** 极验的 key*/private String geetestKey;
}
package com.zhz.config;import com.zhz.geetest.GeetestLib;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author :zhz* @date :Created in 2021/01/02* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description: 极验验证的自动配置**/
@Configuration
@EnableConfigurationProperties(GeetestProperties.class)
public class GeetestAutoConfiguration {private GeetestProperties geetestProperties ;public GeetestAutoConfiguration(GeetestProperties geetestProperties){this.geetestProperties = geetestProperties ;}@Beanpublic GeetestLib geetestLib(){GeetestLib geetestLib = new GeetestLib(geetestProperties.getGeetestId(),geetestProperties.getGeetestKey());return geetestLib ;}
}
/*** @(#)Result.JAVA, 2020年04月02日.* <p>* Copyright 2020 GEETEST, Inc. All rights reserved.* GEETEST PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*/
package com.zhz.geetest;/*** sdk lib包的返回结果信息。*/
public class GeetestLibResult {/*** 成功失败的标识码,1表示成功,0表示失败*/private int status = 0;/*** 返回数据,json格式*/private String data = "";/*** 备注信息,如异常信息等*/private String msg = "";public void setStatus(int status) {this.status = status;}public int getStatus() {return status;}public void setData(String data) {this.data = data;}public String getData() {return data;}public void setMsg(String msg) {this.msg = msg;}public String getMsg() {return msg;}public void setAll(int status, String data, String msg) {this.setStatus(status);this.setData(data);this.setMsg(msg);}@Overridepublic String toString() {return String.format("GeetestLibResult{status=%s, data=%s, msg=%s}", this.status, this.data, this.msg);}
}

5.5、获取极验的第一次数据包

5.5.1、在资源服务器里面放行路径

我用的jwt+auth2.0,你们自己去放行路径--》"/gt/register"

5.5.2、添加控制器 GeetestController

package com.zhz.controller;import com.zhz.geetest.GeetestLib;
import com.zhz.geetest.GeetestLibResult;
import com.zhz.model.R;
import com.zhz.util.IpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;/*** @author :zhz* @date :Created in 2021/01/02* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description:**/
@RestController
@RequestMapping("/gt")
public class GeetestController {@Autowiredprivate GeetestLib geetestLib;@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@GetMapping("/register")public R<String> register(String uuid) {String digestmod = "md5";Map<String, String> paramMap = new HashMap<String, String>();paramMap.put("digestmod", digestmod);paramMap.put("user_id", uuid);paramMap.put("client_type", "web");ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();paramMap.put("ip_address", IpUtil.getIpAddr(servletRequestAttributes.getRequest()));//ip地址GeetestLibResult result = geetestLib.register(digestmod, paramMap); // 极验服务器交互// 将结果状态写到session中,此处register接口存入session,后续validate接口会取出使用// 注意,此demo应用的session是单机模式,格外注意分布式环境下session的应用redisTemplate.opsForValue().set(GeetestLib.GEETEST_SERVER_STATUS_SESSION_KEY, result.getStatus(), 180, TimeUnit.SECONDS);
//        request.getSession().setAttribute( result.getStatus());redisTemplate.opsForValue().set(GeetestLib.GEETEST_SERVER_USER_KEY + ":" + uuid, uuid, 180, TimeUnit.SECONDS);
//        request.getSession().setAttribute("userId", userId);// 注意,不要更改返回的结构和值类型return R.ok(result.getData());}
}

5.5.3、在gateway网关里面添加 CorsConfig

package com.zhz.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;/*** @author :zhz* @date :Created in 2020/12/20* @version: V1.0* @slogan: 天下风云出我辈,一入代码岁月催* @description: 解决跨域问题**/
@Configuration
public class CorsConfig {@Beanpublic CorsWebFilter corsWebFilter(){CorsConfiguration corsConfiguration=new CorsConfiguration();corsConfiguration.addAllowedHeader("*");corsConfiguration.addAllowedOrigin("*");corsConfiguration.addAllowedMethod("*");UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource=new UrlBasedCorsConfigurationSource();urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",corsConfiguration);return new CorsWebFilter(urlBasedCorsConfigurationSource);}
}

具体代码:看本人gitee上:请点击这

下面是本人的公众号:(有兴趣可以扫一下,文章会同步过去)

我是小白弟弟,一个在互联网行业的小白,立志成为一名架构师
https://blog.csdn.net/zhouhengzhe?t=1

极验验证(滑动验证)的使用相关推荐

  1. 破解极验三代滑动验证,成功率百分之百(三):构造参数,发起请求

    声明 原创文章,请勿转载! 本文内容仅限于安全研究,不公开具体源码.维护网络安全,人人有责. 环节概述 首先我们还是需要使用请求转发工具,把目标代码替换为我们处理过的代码. 观察验证过程中触发了哪些请 ...

  2. Python Selenium 破解极验(GeeTest)滑动验证

    ArmourGeeTestArmourGeeTestArmourGeeTest [TOS] 本项目仅供交流学习,有疑问请在issue中提出: 本项目不提供面向任何商业需求的版本迭代: 关于本项目源码的 ...

  3. 使用极验【行为验证】实现人机交互验证

    官网:https://docs.geetest.com/sensebot/apirefer/api/web 流程与原理 待补充-- 方法 1.引入极验js,调用初始化方法 require(" ...

  4. 网络爬虫-破解极验三代滑动验证码

    什么是"极验"? 如果你是从事爬虫相关工作的,那么一定对这两个字不会陌生的. 极验是首家「行为式验证」安全技术服务提供商,并以提供验证码服务而闻名.我们日常会登录一些网站,有的网站 ...

  5. Python爬虫解决极验(geetest)滑动验证码

    csdn_okcheng 滑动验证码的识别介绍 实现步骤: ① 初始化 ② 模拟登录填写,点开滑块验证 ③ 获取并储存有无缺口的两张图片 ④ 获取缺口位置 ⑤ 获取移动轨迹 ⑥ 按照轨迹拖动,完全验证 ...

  6. Django中使用极验Geetest滑动验证码

    一,环境部署 1.创建一个django测试项目 此处省略... 二,文档部署 1.下载安装python对应的SDK 使用命令从Github导入完整项目:git clone https://github ...

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

    **一,环境部署 ** 1.创建一个django测试项目 二,文档部署 1.下载安装python对应的SDK 使用命令从Github导入完整项目:git clone https://github.co ...

  8. 给html5添加极验,Django中使用极验Geetest滑动验证码过程解析

    一,环境部署 1.创建一个django测试项目 二,文档部署 1.下载安装python对应的SDK 使用命令从Github导入完整项目:git clone https://github.com/Gee ...

  9. 极验三代滑块验证分析

    声明 原创文章,请勿转载! 本文内容仅限于安全研究,不公开具体源码.维护网络安全,人人有责. w值生成逆向分析 目标链接:aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby9 ...

  10. 爬虫入门经典(十九) | 难度提升,破解极验验证码

      大家好,我是不温卜火,是一名计算机学院大数据专业大三的学生,昵称来源于成语-不温不火,本意是希望自己性情温和.作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己 ...

最新文章

  1. python遍历链表_Python;链表和遍历!
  2. AC日记——魔方 洛谷 P2007
  3. 【python数据挖掘课程】十五.Matplotlib调用imshow()函数绘制热图
  4. linux命令大写输入,Linux命令行:对内容进行大小写字符转换 ????
  5. [*转*] 开发B2C电子商务系统(ASP.NET)--多年前的老文章
  6. c专家编程 读书笔记
  7. 教你用Python 编写 Hadoop MapReduce 程序
  8. bzoj 4563 [Haoi2016]放棋子 错位排列+高精度
  9. 复杂多个合约部署验证方法
  10. 纯CSS3实现牛奶般剔透的3D按钮特效
  11. 函数名称修饰符__cdelcl __fastcall 与__stdcall
  12. Tkinter模块GUI界面化编程实战(三)——2048小游戏(含详解及完整源码、完整程序下载链接)
  13. almon多项式_计量经济学 总结.docx
  14. Java的随机数原理
  15. Sql Server专题三:SQL操作与技巧
  16. Linux命令hostname -i
  17. 微信小程序傻瓜制作_怎么能免费制作自己的微信小程序?
  18. p5.js创意绘图(1)动态图形
  19. Required field ‘serverProtocolVersion‘ is unset! User: root is not allowed to impersonate root
  20. linux中sh脚本的写法

热门文章

  1. 【每天学点管理】—绩效面谈的两个技巧
  2. Blinker点灯科技绑定GitHub增加设备数量到10个
  3. Heavy Transportation(Dijkstra算法)
  4. 《职业形象与商务礼仪》
  5. 研读Joint Multi-modal Aspect-Sentiment Analysis with Auxiliary Cross-modal
  6. Unity 烘焙问题
  7. android收集备忘录恢复工具,备忘录不小心删了怎么恢复?专业恢复工具分享
  8. 用Word编辑论文的小经验(转)
  9. ie调用java闪退_IE11老是闪退怎么办 IE11闪退解决教程方法汇总
  10. Week 5: Management of the Sporadic Nature of Data Flows 4 - UE-Triggered Service Request