-
2021-08-03 01:08:50
一个非常好用的验证码识别工具类api接口
群发?批量操作?验证码?可能乖孩子对于这些单个有了解,但是对于合在一起就不知道其存在的意义。这个对
于我们日常的生活可能是没有什么用处的,但是对于需要批量检测,顶贴,群发的软件使用者却是一点也不陌生的。
全自动打码平台如何解决群发,批量操作中验证码的难题
举例说明,今天我要加1000个群,当然其他的也是一样的,那么我就会有1000个验证码产生,如果我们输入
一个验证码字母的速度,大概是需要一到两个小时,但是这样的时间成本其实是一种极大的浪费,我们该如何做到
验证码的快速解决呢?
答题吧今天就为各种会遇到验证码的用户提供一个目前较为优秀的解决方案。
一、前期的方案运作
可以在操作运作的过程中先进行验证码的识别测试,了解验证码是别的准确率;
二、技术解决方案
针对不同的行业对于验证码的不同需求,我们的API接入系统能够帮助软件工作者进行快速的软件接入,有目
前比较流行的多种语言,使用比较多的有易语言,JAVA,按键精灵,C+等等十多种接口接入;
全自动打码平台如何解决群发,批量操作中验证码的难题
三、验证码识别方案
识别内容,从客户端的识别到工作端的传输
我们中间配置有高端服务器进行分布式架构处理,快速进行验证码识别传输
保证每一个验证码准确无误的到达工作者端进行识别。
HTTP接口说明
答题(上传)
上传题目图片返回结果.
请求URL
http://www.dati8.com/create.aspx
支持格式
application/json
HTTP请求方式
POST
请求参数
必选类型说明
usernametruestring用户名。
passwordtruestring用户密码(MD5加密后取后16位作为密码(小写字母))
typeidtrueint题目类型
timeoutfalseint任务超时时间,默认与最小值为60秒。
softidtrueint软件ID,开发者可自行申请。
softkeytruestring软件KEY,开发者可自行申请。
imagetruebyte只支持原始图二进制数据。
注意事项
1.开发时需要修改HTTP请求默认超时时间,具体数值需要大于任务超时的timeout参数。
2.特殊题如:中文、选择、类型较难完成的请把任务超时(timeout参数)设置大于100秒,以便满足任务重新分配机制。
3.网络环境中HTTP劫持会影响使用结果。
4.任务执行中切勿断拨或切断网络,否则无法接收结果。
返回结果
正确返回
JSON:{"Result":"答题结果","id":"题目Id(报错使用)"}
错误返回
文本消息
开发建议
推荐各开发者JSON方式为数据返回,为了代码运行更加健壮数据返回后先判断Result和Id两个分支是否存在,如果返回数据没有这两个分支就完全可以当错误返回处理。
错题报错
错题报错
答题结果错误报告
请求URL
http://www.dati8.com/Error.aspx
支持格式
application/json
HTTP请求方式
POST
请求参数
必选类型说明
usernametruestring用户名。
passwordtruestring用户密码(MD5加密后取后16位(小写字母))。
softidtrueint软件ID,开发者可自行申请。
softkeytruestring软件KEY,开发者可自行申请。
idtrueint报错题目的ID
注意事项
网络环境中HTTP劫持会影响使用结果。
返回结果
JSON:{"Result":"提交结果"}
查询
查询
查询用户信息
请求URL
http://www.dati8.com/info.aspx
支持格式
application/json
HTTP请求方式
POST
请求参数
必选类型说明
usernametruestring用户名。
passwordtruestring用户密码(用MD5加密后取后16位作为密码(小写字母))。
注意事项
网络环境中HTTP劫持会影响使用结果。 任务执行中切勿断拨或切断网络,否则无法接收结果。
返回结果
JSON:{"Score":"剩余点数","HistoryScore":"历史使用点数","TotalTopic":"答题总数"}
注册
注册
注册答题帐号
请求URL
http://www.dati8.com/register.aspx
支持格式
application/json
HTTP请求方式
POST
请求参数
必选类型说明
usernametruestring用户名。
passwordtruestring用户密码(明文长度(6-16位)只能是字母或数字)。
emailtruestring邮箱
Deveusernametruestring开发者用户名
Devepasswordtruestring开发者密码(用MD5加密后取后16位作为密码(小写字母))。
注意事项
网络环境中HTTP劫持会影响使用结果。 任务执行中切勿断拨或切断网络,否则无法接收结果。
返回结果
{"Result":"注册成功"}
充值
充值
用户充值
请求URL
http://www.dati8.com/recharge.aspx
支持格式
json
HTTP请求方式
POST
请求参数
必选类型说明
usernametruestring要充值的用户名。
idCardtruestring充值卡号。
Cardpasswordtruestring充值卡密码
注意事项
网络环境中HTTP劫持会影响使用结果。 任务执行中切勿断拨或切断网络,否则无法接收结果。
返回结果
{"Result":"充值结果"}
更多相关内容 -
易语言-验证码自动识别服务端 通杀识别库
2021-06-28 22:39:56服务端采用的光速模块例程,缺点:限制100连接数,所有文件已打包,自行搭建服务器 源码调用了精易及鱼刺多线程模块。 调用方法 服务器地址 post 字节集提交图片 如果是安卓端按键精灵或其他用途 可尝试自行把源码... -
Python用 KNN 进行验证码识别的实现方法
2020-12-24 13:11:40其中一个逻辑是通过用户的教务系统来确认用户是一名在校大学生,基本的想法是通过用户的账号和密码,用爬虫的方法来确认信息,但是许多教务系统都有验证码,当时是通过本地服务器去下载验证码,然后分发给客户端,... -
完美验证码识别系统
2018-01-07 03:49:10完美验证码识别系统V3.2 1.增加DLL识别返回方式2和3具体看我的函数.txt里说明,主要是增加一个可以返回识别后的总体信任度.这个值你可以给它个阀值,比如说如果总体信任度小于60,那么你就不提交服务器,直接重新获取... -
本地部署的英文数字验证码识别插件 按键精灵、触摸精灵、触动精灵、Python等所有语言和平台都可方便对接 ...
2022-01-26 14:34:231.本插件需一台电脑或者服务器做验证码识别(WIN10、11、2012、2016、2019系统均可)。 2.本插件已经将所有环境都封包完整了,生成了启动程序.exe文件,双击直接开启服务,不用配置环境。 2.插件是以web服务的形式... -
完美验证码识别系统V3.2.1.rar
2020-07-26 10:06:25完美验证码识别系统V3.2 1.增加DLL识别返回方式2和3具体看我的函数.txt里说明,主要是增加一个可以返回识别后的总体信任度.这个值你可以给它个阀值,比如说如果总体信任度小于60,那么你就不提交服务器,直接重新获取... -
优优云验证码识别
2014-09-06 20:17:17优优云验证码识别 -
短信验证码_02.搭建服务器环境
2021-08-02 07:15:36Node 搭建服务器环境1.在项目下新建一个文件夹 sms-send,并用编辑器打开2.用终端进入 sms-send 文件夹路径2.1.自动创建 package.json命令:npm init --yes 创建好之后就这个样子:2.2. 装对应的模块npm install ...Node 搭建服务器环境
1.在项目下新建一个文件夹 sms-send,并用编辑器打开
2.用终端进入 sms-send 文件夹路径
2.1.自动创建 package.json
命令:npm init --yes 创建好之后就这个样子:
2.2. 装对应的模块
npm install express body-parser request querystring --save
3.创建index.js文件
package.json 里默认入口是 index.js 。趁装模块的时间,我们可以先去创建 index.js
4.下载安装 postman
5.在 sms-send 文件夹终端安装 nodemon
npm install nodemon -g
6.index.js代码
//1.引入模块
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const querystring = require('querystring');
//2.实例化app,监听对应服务
const app = express();
//3.中间件拿过来以后,能正常获取前端传递的数据
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//4.设置对应接口,可以访问对应地址
app.get('/',(req,res) => {
res.send('测试使用的');
});
//5.设置端口号
const port = process.env.PORT || 5000; //没有服务器,暂时使用5000
//6.监听端口号是否有被访问,被访问的话,走入一个箭头函数
app.listen(port,() => {
console.log(`server is running on port ${port}`);
})
6.1.关于拿到 body-parser
搜索 body-parser
找到中间件
7.运行
在sms-send文件夹终端:nodemon
没有装nodemon:node index.js
8.来浏览器测试
这样就完成了基本的服务器环境搭建
-
验证码识别-Java版
2021-01-20 10:36:56前段时间用Java写了个爬虫爬教务处网站,于是有朋友问我是怎么实现验证码识别的,在此将这个小方法分享出来!前段时间用Java写了个爬虫爬教务处网站,于是有朋友问我是怎么实现验证码识别的,在此将这个小方法分享出来!
PS:Java也是可以做爬虫的哦~因为对Java熟悉些,所有就用Java写的,打成jar包放服务器,写个cron定时启动也是方便的很呢!
正文前述:关于验证码识别的算法,我之前也了解过一些,现在一般用卷积神经网络来做。虽然Github上相关做好的算法很多,但是这些模型也都还面临着一个问题,就是训练,我们只是拿来应用一下,为什么要做这么多无关的工作呢,而且初期的识别率还不高。所以我就去各大云市场找了一些验证码识别的API,最后在腾讯云找到一个比较好的接口,而且价格也算是合理的。1块钱100次,对自己做爬虫来说,完全是够了的。
本文不是做验证码识别算法,仅仅是一个应用和工具集的封装。方便你我他!
0x01.API的购买
- 在腾讯云中搜索验证码识别:
- 链接:https://market.cloud.tencent.com/products/21094
- 购买后可以获得secretId和secretKey。
0x02.工具集的封装
- 参考官方给的调用案例,并且这个接口需要的是图片的base64编码,所以对这些操作做了一些封装。
1.Base64工具集
import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; @SuppressWarnings("restriction") public class Base64Utils { public static void main(String[] args) throws Exception { //本地图片地址 String url = "D:\\DeskTop\\验证码识别\\code1.jpg"; //在线图片地址 String onlineUrl = ""; String imgBase64=Base64Utils.ImageToBase64ByOnline(onlineUrl); System.out.println(imgBase64); } /** * 本地图片转换成base64字符串 * @param imgFile 图片本地路径 * @return */ public static String ImageToBase64ByLocal(String imgFile) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 InputStream in = null; byte[] data = null; // 读取图片字节数组 try { in = new FileInputStream(imgFile); data = new byte[in.available()]; in.read(data); in.close(); } catch (IOException e) { e.printStackTrace(); } // 对字节数组Base64编码 BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data);// 返回Base64编码过的字节数组字符串 } /** * 在线图片转换成base64字符串 * @param imgURL 图片线上路径 * @return * */ public static String ImageToBase64ByOnline(String imgURL) { ByteArrayOutputStream data = new ByteArrayOutputStream(); try { // 创建URL URL url = new URL(imgURL); byte[] by = new byte[1024]; // 创建链接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); InputStream is = conn.getInputStream(); // 将内容读取内存中 int len = -1; while ((len = is.read(by)) != -1) { data.write(by, 0, len); } // 关闭流 is.close(); } catch (IOException e) { e.printStackTrace(); } // 对字节数组Base64编码 BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data.toByteArray()); } /** * base64字符串转换成图片 * @param imgStr base64字符串 * @param imgFilePath 图片存放路径 * @return */ public static boolean Base64ToImage(String imgStr,String imgFilePath) { // 对字节数组字符串进行Base64解码并生成图片 if (imgStr==null||imgStr=="") // 图像数据为空 return false; BASE64Decoder decoder = new BASE64Decoder(); try { // Base64解码 byte[] b = decoder.decodeBuffer(imgStr); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) {// 调整异常数据 b[i] += 256; } } OutputStream out = new FileOutputStream(imgFilePath); out.write(b); out.flush(); out.close(); return true; } catch (Exception e) { return false; } } }
2.验证码接口调用
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.TimeZone; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Encoder; public class VcodeIdentifi { //云市场分配的密钥Id public static final String secretId = ""; //云市场分配的密钥Key public static final String secretKey = ""; public static final String source = "market"; //验证码的位数 public static final String number="4"; //ne:英文数字组合,dn:纯数字,de:纯英文 public static final String pri_id="ne"; public static String VcodeIdentification(String IMG_BASE64) { Calendar cd = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); String datetime = sdf.format(cd.getTime()); // 签名 String auth = null; try { auth = calcAuthorization(source, secretId, secretKey, datetime); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } // 请求方法 String method = "POST"; // 请求头 Map<String, String> headers = new HashMap<String, String>(); headers.put("X-Source", source); headers.put("X-Date", datetime); headers.put("Authorization", auth); // 查询参数 Map<String, String> queryParams = new HashMap<String, String>(); // body参数 Map<String, String> bodyParams = new HashMap<String, String>(); bodyParams.put("number", number); bodyParams.put("pri_id", pri_id); bodyParams.put("v_pic", IMG_BASE64); // url参数拼接 String url = "http://service-98wvmcga-1256810135.ap-guangzhou.apigateway.myqcloud.com/release/yzm"; if (!queryParams.isEmpty()) { try { url += "?" + urlencode(queryParams); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } BufferedReader in = null; try { URL realUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); conn.setRequestMethod(method); // request headers for (Map.Entry<String, String> entry : headers.entrySet()) { conn.setRequestProperty(entry.getKey(), entry.getValue()); } // request body Map<String, Boolean> methods = new HashMap<>(); methods.put("POST", true); methods.put("PUT", true); methods.put("PATCH", true); Boolean hasBody = methods.get(method); if (hasBody != null) { conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setDoOutput(true); DataOutputStream out = new DataOutputStream(conn.getOutputStream()); out.writeBytes(urlencode(bodyParams)); out.flush(); out.close(); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; String result = ""; while ((line = in.readLine()) != null) { result += line; } //System.out.println(result); return result; } catch (Exception e) { System.out.println(e); e.printStackTrace(); } finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return null; } public static String calcAuthorization(String source, String secretId, String secretKey, String datetime) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException { String signStr = "x-date: " + datetime + "\n" + "x-source: " + source; Mac mac = Mac.getInstance("HmacSHA1"); Key sKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), mac.getAlgorithm()); mac.init(sKey); byte[] hash = mac.doFinal(signStr.getBytes("UTF-8")); String sig = new BASE64Encoder().encode(hash); String auth = "hmac id=\"" + secretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\"" + sig + "\""; return auth; } public static String urlencode(Map<?, ?> map) throws UnsupportedEncodingException { StringBuilder sb = new StringBuilder(); for (Map.Entry<?, ?> entry : map.entrySet()) { if (sb.length() > 0) { sb.append("&"); } sb.append(String.format("%s=%s", URLEncoder.encode(entry.getKey().toString(), "UTF-8"), URLEncoder.encode(entry.getValue().toString(), "UTF-8") )); } return sb.toString(); } }
3.测试
public class Main { public static void main(String[] args) { String localUrl="D:\\DeskTop\\验证码识别\\code2.jpg"; String imgBase64=Base64Utils.ImageToBase64ByLocal(localUrl); //String onileUrl="http://*.edu.cn/validateCodeAction.do?random=0.41074290098962263"; //String imgBase64=Base64Utils.ImageToBase64ByOnline(onileUrl); String result=VcodeIdentifi.VcodeIdentification(imgBase64); System.out.println(result); } }
- 返回的是json字符串,后续还可以根据需求做进一步的结果处理。
-
Python验证码识别
2020-12-03 06:52:10注意:若使用云服务器 (Windows Server版) 遇到闪退,请按照步骤:我的电脑——属性——管理——添加角色和功能——勾选桌面体验,点击安装,安装之后重启即可。2020/06/01编外:想必各位只是偶然间搜到这篇文章,...注意:若使用云服务器 (Windows Server版) 遇到闪退,请按照步骤:我的电脑——属性——管理——添加角色和功能——勾选桌面体验,点击安装,安装之后重启即可。
2020/06/01编外:
想必各位只是偶然间搜到这篇文章,网上文章参差不齐,标题党很多,能跑起来的开源代码很少,对于能跑起来的代码,也经常遇到以下问题如:内存泄漏,网络参数写死导致更换训练集报错,网络跑其他样本识别率低,没有调用示例等等。
再往下看之前,我可以向你们保证,它绝对会是你所见过的所有验证码有关的文章中最实用,最接近生产水平的。
对小白: 你可以不需要动手写任何一行代码。
对小企业: 它的可用性和稳定性是经得起考验的,在性能上也是同行领先的,可以放心入坑。
因为小编打算转行了,离开这个行业之前总要留下点什么证明自己来过,总有人和我说的这个部署不会调用,可能你们想要的是一行pip就搞定环境的,所以今天给你们安排了麻瓜OCR(MuggleOCR)。
https://pypi.org/project/muggle-ocr
它整合了简单验证码识别通用模型+印刷文字通用识别,并且支持调用本文框架训练的模型。调用只需要三行核心代码:
import time
# STEP 1
import muggle_ocr
import os
# STEP 2
sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.OCR)
root_dir = r"./imgs"
for i in os.listdir(root_dir):
n = os.path.join(root_dir, i)
with open(n, "rb") as f:
b = f.read()
st = time.time()
# STEP 3
text = sdk.predict(image_bytes=b)
print(i, text, time.time() - st)
这真的很简单,应付一般的文字识别和验证码都足够了。(文字识别过几天会更新一下新模型,毕竟0601模型就跑了半天。
1. 前言
本项目适用于Python3.7,GPU>=NVIDIA GTX1050Ti,原master分支新增了GUI配置界面以及编译版本了,是时候写一篇新的文章了。
长话短说,开门见山,网络上现有的代码以教学研究为主,本项目是为实用主义者定制的,只要基本的环境安装常识,便可很好的训练出期望的模型,重定义几个简单的参数任何人都能使用深度学习技术训练一个商业化成品。
笔者选用的时下最为流行的CNN+BLSTM+CTC(CRNN)进行端到端的不定长验证码识别,代码中预留了CNNX(搜不到因为是小编自己拼凑的)/MobileNet/DenseNet121/ResNet50等选项,可以在配置界面中直接选用。首先,介绍个大概吧。
网格结构
predict-CPU
predict-GPU
模型大小
CNN5+Bi-LSTM+H64+CTC
15ms
8ms
2mb
CNN5+CrossEntropy
8ms
2ms
1.5mb
2.环境依赖:
花了超长篇幅介绍了训练环境的基本搭建,主要是给尚未入门的读者看的,老鸟们随便跳过,若不希望在环境上面浪费时间的,欢迎使用编译版,可在文章开头找到下载地址。
关于CUDA和cuDNN版本的问题,不少人很纠结,这里就列出官方通过pip安装的TensorFlow的版本对应表:
Linux
Version
Python version
Compiler
Build tools
cuDNN
CUDA
tensorflow_gpu-1.14.0
3.7
GCC 4.8
Bazel 0.15.0
7.6
9
Windows
Version
Python version
Compiler
Build tools
cuDNN
CUDA
tensorflow_gpu-1.14.0
3.7
MSVC 2015 update 3
Bazel 0.15.0
7.6
10
如果希望使用上面对应之外的搭配的CUDA和cuDNN,可以自行编译TensorFlow,或者去Github上搜索TensorFlow Wheel找到第三方编译的对应版本的whl安装包。提前预警,若是自己编译将会苦难重重,坑很多,这里就不展开了。
2.1 本项目环境依赖
目前在以下主流操作系统平台均测试通过:
操作系统
最低支持版本
Ubuntu
16.04
Windows
7 SP1
MacOS
N/A
本训练项目主要的环境依赖清单如下
依赖
最低支持版本
Python
3.7
TensorFlow-GPU
1.14.0
Opencv-Python
4.1.2.30
Numpy
1.16.0
Pillow
4.3.0
PyYaml
3.13
tqdm
N/A
2.1.1 Ubuntu 16.04 下的 Python 3.7
1)先安装Python环境(有Python 3.7环境的可以忽略)
sudo apt-get install openssl
sudo apt-get install libssl-dev
sudo apt-get install libc6-dev gcc
sudo apt-get install -y make build-essential zlib1g-dev libbz2-dev libreadline-dev $ libsqlite3-dev wget curl llvm tk-dev
wget https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz
tar -vxf Python-3.7.6.tar.xz
cd Python-3.7.6
./configure --prefix=/usr/local --enable-shared
make -j8
sudo make install -j8
经过上面指令就安装好Python3.7环境了,如果提示找不到libpython3.7m.so.1.0就到/usr/local/lib路径下将该文件复制一份到/usr/lib和/usr/lib64路径下。
2)安装相关依赖(这一步Windows和Linux通用)
可以直接在项目路径下执行pip3 install -r requirements.txt安装所有依赖,注意这一步是安装在全局Python环境下的,强烈建议使用虚拟环境进行项目间的环境隔离,如Virtualenv或Anaconda等等。
我一般使用的是Virtualenv,有修改代码需要的,建议安装PyCharm作为Python IDE
virtualenv -p /usr/bin/python3 venv # venv is the name of the virtual environment.
cd venv/ # venv is the name of the virtual environment.
source bin/activate # to activate the current virtual environment.
cd captcha_trainer # captcha_trainer is the project path.
pip3 install -r requirements.txt
2.1.2 Ubuntu 16.04 下的 CUDA/cuDNN
网上看到过很多教程,我自己也部署过很多次,Ubuntu 16.04遇到的坑还是比较少的。14.04支持就没那么好,如果主板不支持关闭SecureBoot的话千万不要安装Desktop版,因为安装好之后一定会无限循环在登陆界面无法进入桌面。
网上教程说要加驱动黑名单什么的我直接跳过了,亲测没那个必要。就简单的几步:
1. 下载好安装包
注意下载runfile类型的安装包,deb安装会自动安装默认驱动,极有可能导致登陆循环
NVIDIA 驱动下载:https://www.geforce.cn/drivers
CUDA 下载地址:https://developer.nvidia.com/cuda-downloads
cuDNN 下载地址:https://developer.nvidia.com/cudnn (需要注册NVIDIA账号且登陆,下载deb安装包)
2. 关闭图形界面
Ctrl+alt+F1进入字符界面,关闭图形界面
sudo service lightdm stop
3. 安装Nvidia Driver
命令中的版本自己对应下载的版本改,在上面的下载地址根据自己的显卡型号下载最新版,切记是runfile格式的安装包。
sudo chmod a+x NVIDIA-Linux-x86_64-384.90.run //获取执行权限
sudo ./NVIDIA-Linux-x86_64-384.90.run –no-x-check –no-nouveau-check –no-opengl-files //安装驱动
安装成功以后使用以下命令验证,如果显示显卡信息则表示安装成功
nvidia-smi
4. 安装CUDA
1)先安装一些系统依赖库
sudo apt-get install freeglut3-dev build-essential libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev
执行安装程序,按指示无脑继续就好了,如果提示是否安装驱动选不安装。
sudo sh cuda_9.0.176_384.81_linux.run
安装完如果环境变量没配上去,就写到 ~/.bashrc 文件的尾部
export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
然后在终端执行 sudo ldconfig更新,安装完毕就可以重启机器重启图形界面了。
sudo service lightdm start
2.1.3 Windows 系统
在Windows其实简单很多,只要到官网下载安装包无脑安装就可以了,下载连接同Ubuntu,先安装Python,显卡驱动,CUDA,然后下载对应的cuDNN替换到对应路径即可。
3 使用
在训练之前,有不少群友经常问我“训练4位数英文数字需要多少样本?”诸如此类的问题,我这里统一做个回复,样本数量主要是看样本的特征复杂度而定。
这里可以提供几个参考依据: 是否变形?是否旋转?是否有复杂背景干扰?是否多种字体?字符集(分类数)多大?位数(标签数)多少?
一般简单的几百个样本(需要自行调整 验证集大小 和 验证批次大小 )即可。
稍微复杂的几千个样本一般都能搞定。
特别复杂的几万样本起。
中文这种几千个分类的一般十万起。
注:只准备一百个不到样本的亲们,千万不要尝试训练测试,因为根本跑不起来。
入手的第一步环境搭建好了,那就是准备跑代码了,还是有几个必要的条件,巧妇难为无米之炊,首先,既然是训练,要先有训练集,有一个新手尝鲜的训练集,是mnist手写识别的例子,可以在腾讯云下载:https://share.weiyun.com/5pzGF4V
,现在万事俱备,只欠东风。
3.1 定义一个模型
本项目基于参数化配置,不需要改动任何代码,可以通过可视化界面操作训练几乎任何字符型图片验证码。训练框架界面可以大致划分为几个部分:
Neural Network - 神经网络区
Project Configuration - 项目配置区
Sample Source - 样本源配置区
Training Configuration - 训练配置区
Buttons - 功能控制区
依此类推的训练配置的步骤如下:
神经网络区 的配置项看起来很多,对于新手来说,可以直接使用默认的配置:CNNX+GRU+CTC+C1组合(CNN前置网络+GRU+CTC+单通道)。
项目配置区 的配置项在网络选好之后配置项目名,按回车或者点击空白处确认。
样本源配置区 的配置项用来配置样本源的路径,训练样本是根据此路径进行打包成TFRecords格式,验证样本可以不指定,使用[Validation Set Num]参数随机从训练集总抽样成验证集。
训练配置区 的配置项负责定义训练完成的条件如:结束准确率,结束COST,结束Epochs,批次大小
功能控制区 的配置项,设置完上面步骤,先点击[Make Dataset] 打包样本,再点击[Start Training]开始训练。
以下部分有基础的读者们可以了解一下:
如若使用CrossEntropy作为解码器需要注意标签数LabelNum和图片尺寸需要满足的关系,因为网络为多标签而设计(一般的多标签采用直接连接多个分类器),卷积层的输出 outputs 经过了以下变换:
Reshape([label_num, int(outputs_shape[1] / label_num)])
为了保证运算 int(outputs_shape[1] / label_num) 能够取得正整数,也意味着他们之间存在某种关系,对于CNN5+Cross Entropy的网络结构,Conv2D层的步长皆为1,那么需要保证以下关系成立:
\[mod(\frac{输入宽度\times输入高度\times输出层参数}{池化步长^{池化层数}\times标签数})= 0
\]
所以有时候需要Resize网络输入的Shape
网络
池化步长^池化层数
输出层参数
CNN5
16
64
CNNX
8
64
ResNet50
16
1024
DenseNet
32
2048
例如使用CNN5+CrossEntropy组合,则输入宽度与输入高度需要满足:
\[mod(\frac{输入宽度\times输入高度\times64}{16\times标签数})= 0
\]
同理如果CNN5+RNN+CTC,卷积层之后的输出经过以下变换:
Reshape([-1, outputs_shape[2] * outputs_shape[3]])
原输出(batch_size, outputs_shape[1], outputs_shape[2], outputs_shape[3]),RNN层的输入输出要求为(batch, timesteps, num_classes),为了接入RNN经过以上操作,那么又引出一个Time Step的概念,所以timesteps的值也是 outputs_shape[1],而CTC Loss要求的输入为 [batch_size, frames, num_labels],若是 timesteps 小于标签数则无法计算损失,也就无法找损失函数中找到极小值,梯度何以下降。timesteps 最合理的值一般是标签数的2倍,为了达到目的,也可以通过Resize网络输入的Shape解决,一般情况timesteps直接关联于图片宽度,大多情况只要按比例放大宽度即可。
ExtractRegex 参数:
注意:如果训练集的命名格式和我提供的新手训练集不一样,请根据实际情况修改ExtractRegex的正则表达式。目前只支持在yaml配置文件中直接修改,尚未提供GUI界面修改的支持。 DatasetPath 和SourcePath参数允许多个路径,这种操作适用于需要将多种样本训练为一个模型,或者希望训练一套通用泛化模型的人。
字符集Category其实大多数情况下不需要修改,一般的图形验证码离不开数字和英文,而且一般来说是大小写不敏感的,不区分大小写,因为打码平台收集的训练集质量参差不齐,有些大写有些小写,不如全部统一为小写,默认ALPHANUMERIC_LOWER则会自动将大写的转为小写,字符集可定制化很灵活,除了配置备注上提供的几种类型,还可以训练中文,自定义字符集用list表示,示例如下:
Category: ['常', '世', '宁', '慢', '南', '制', '根', '难']
如果是单标签分类,可以配合LabelNum=1,例如:
Category: ["航母", "雨靴", "毛线", "安全帽", "调色板", "海鸥", "日历", "网球拍", ......]
其文件名示例:航母_1231290424123.png
如果是多标签分类,可以配合LabelSplit=&,例如:
Category: ["航母", "雨靴", "毛线", "安全帽", "调色板", "海鸥", "日历", "网球拍", ......]
其文件名示例:航母&雨靴&毛线_1231290424123.png
可以自己根据收集训练集的实际字符集使用率来定义,也可以无脑网上找3500常用字来训练,注意:中文字符集一般比数字英文大很多,刚开始收敛比较慢,需要更久的训练时间,也需要更多的样本量,请量力而行
形如上图的图片能轻松训练到95%以上的识别率。
ImageWidth、ImageHeight只要和当前图片尺寸匹配即可,其实这里的配置主要是为了方便后面的部署智能策略。
Pretreatment参数:
该参数是用来做图片预处理的,例如形如以下的GIF动图,
可以使用ConcatFrames参数选取帧对两帧进行水平拼接,适用于处理滚动型GIF,而闪烁型GIF可以使用BlendFrames参数进行融合。
3.2 开始训练
经过 采集标注样本形如 xxx_随机数.png
打包样本
通过GUI界面的 [Make Dataset] 或者 make_dataset.py 直接打包。
注意:使用源码运行本项目的功能模块需要具备一定的语言基础,参数修改的部分和示例已预留好,尽量不修改核心类或函数的代码以免出现错误。
按照上面的介绍,配置只要修改极少数的参数对应的值,就可以开启正式的训练之旅了,具体操作如下:
可以直接使用 PyCharm 的 Run,执行 trains.py,也可以在激活Virtualenv下使用终端亦或在安装依赖的全局环境下执行,但本文建议全程使用GUI界面进行操作,使用GUI仅需启动 app.py 即可。
python3 trains.py
剩下的就是等了,看过程,等结果。
正常开始训练的模样应该是这样的:
训练结束会在项目的out路径下生成一个包含pb文件的graph目录和包含yaml文件的model目录,下面该到部署环节了。
3.3 部署
真的很有必要认真的介绍一下部署项目,比起训练,这个部署项目倾注了笔者更多的心血,为什么呢?
项目地址:https://github.com/kerlomz/captcha_platform
如希望将本系统集成于自己的项目中的可以参考python-sdk的使用:
https://pypi.org/project/muggle-ocr/
该项目的核心基于 captcha_platform/sdk/pb/sdk.py 可以根据需要自行修改,抑或直接使用MuggleOCR 调用训练框架生产的模型。(具体调用方法可点击上面链接有对应的文档介绍)
真的值得了解的几点
同时管理多个模型,支持模型热拔插
灵活的版本控制
支持批量识别
服务智能路由策略
首先笔者重写了TensorFlow的Graph会话管理,设计会话池,允许同时管理多模型,实现多模型动态部署方案。
1) 训练好的 pb模型只要放在部署项目的graph路径下,yaml模型配置文件放在model, 即可被服务发现并加载。(用SDK调用时,两者置于同一目录下)
2) 如果需要卸载一个正在服务的模型,只需要在model中删除该模型的yaml配置文件,在graph中删除对应的pb模型即可。
3) 如果需要更新一个已经服务中的模型,只需修改新版的模型yaml配置文件的版本号高于原模型的版本号,按先放pb后放yaml的顺序,服务便会自动发现新版的模型并加载使用,旧的模型将因版本低于新版模型不会被调用,可以按照上述的卸载方法卸载已被弃用的模型释放内存。
上面的操作中无需重启服务,完全的无缝切换
其次,一套服务想要服务于各式各样的图像识别需求,可以定义一套策略,训练时将所有尺寸一样的图片训练成一个模型,服务根据图片尺寸自动选择使用哪个模型,这样的设计使定制化和通用性共存,等积累到一定多样的训练集时可以将所有的训练集合到一起训练一个通用模型,亦可以彼此独立,每个模型的叠加仅仅增加了少量的内存或显存,网上的方案大多是不同的模型单独部署一套服务,每个进程加载了一整套TensorFlow框架势必是过于庞大和多余的。
用到批量识别需求的人相对少很多这里就不展开介绍了。但是这里给出一个12306的例子:
FieldParam:
CorpParams: [
{
"start_pos": [118, 0],
"interval_size": [0, 0],
"corp_num": [1, 1],
"corp_size": [60, 30]
},
{
"start_pos": [5, 40],
"interval_size": [5, 5],
"corp_num": [4, 2],
"corp_size": [66, 66]
}
]
OutputCoord: True
该参数可以用于大图的裁剪组成一批小图作为一个批次的输入,改用法可以避免多次调用。
但是识别项目提供了多套可选的服务有:gRPC,Flask,Tornado,Sanic,其中Flask和Tornado提供了加密接口,类似于微信公众号开发接口的SecretKey和AccessKey接口,感兴趣的可以在demo.py中阅读调用源码了解。
部署的使用可以经过package.py编译为可执行文件,这样可以免去更换机器环境安装的烦恼,部署项目安装流程同训练项目,项目中提供的requirements.txt已经将所需的依赖都列清楚了,强烈建议部署项目安装cpu版TensorFlow。
本项目部署推荐使用Tornado版,功能最齐全,性能最为稳定。
Linux:
Tornado:
# 端口 19952
python3 tornado_server.py
Flask
# 方案1,裸启动, 端口 19951
python flask_server.py
# 方案2,使用gunicorn,端口 5000
pip install gunicorn
gunicorn -c deploy.conf.py flask_server:app
Sanic:
# 端口 19953
python3 sanic_server.py
gRPC:
# 端口 50054
python3 grpc_server.py
编译版(基于Tornado)
# 前台运行
./captcha_platform_tornado
#后台运行
nohup ./captcha_platform_tornado &
Windows:
Windows平台下都是通过python3 xxx_server.py启动对应的服务,注意,Tornado、Flask、Sanic的性能在Windows平台都大打折扣,gRPC是Google开源的RPC服务,有较为优越的性能。
编译版直接运行编译后的exe可执行文件即可。
3.4 调用/测试
1. Tornado服务:
请求地址
Content-Type
参数形式
请求方法
具体参数:
参数名
必选
类型
说明
image
Yes
String
Base64 编码
model_name
No
String
模型名,yaml配置中可绑定
need_color
No
String
颜色过滤,black/red/blue/yellow/green/white
output_split
No
String
多标签分割字符
请求为JSON格式,形如:{"image": "base64编码后的图像二进制流"}
返回结果:
参数名
类型
说明
message
String
识别结果或错误消息
code
String
状态码
success
String
是否请求成功
该返回为JSON格式,形如:{"message": "xxxx", "code": 0, "success": true}
2. Flask服务:
请求地址
Content-Type
参数形式
请求方法
请求参数和返回格式同上
3. Sanic服务:
请求地址
Content-Type
参数形式
请求方法
请求参数和返回格式同上
4. gRPC服务:
需要安装依赖,grpcio、grpcio_tools和对应的grpc.proto文件,可以直接从项目中的示例代码demo.py中提取。
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. ./grpc.proto
grpcio、grpcio_tools 是根据 grpc.proto 使用上述命令生成的。
class GoogleRPC(object):
def __init__(self, host: str):
self._url = '{}:50054'.format(host)
self.true_count = 0
self.total_count = 0
def request(self, image, model_type=None, model_site=None):
import grpc
import grpc_pb2
import grpc_pb2_grpc
channel = grpc.insecure_channel(self._url)
stub = grpc_pb2_grpc.PredictStub(channel)
response = stub.predict(grpc_pb2.PredictRequest(
image=image, split_char=',', model_type=model_type, model_site=model_site
))
return {"message": response.result, "code": response.code, "success": response.success}
if __name__ == '__main__':
result = GoogleRPC().request("base64编码后的图片二进制流")
print(result)
3.5 奇技淫巧
该项目还可以直接用于识别带颜色的验证码,部署项目middleware/impl/color_extractor.py基于k-means实现了颜色分离模块,可用于处理如下形式的验证码:
还有一种方案是同时预测验证码和每个字符对应的颜色,不过这需要修改现有的神经网络进行支持,在最后一层修改为双输出,一个输出颜色,一个输出对应字符,这对于样本标注的要求较高,也提高的成本,所以如果能用无限生成样本,那问题就迎刃而解了,比如上图,笔者就写了样本生成代码,感兴趣的可以移步:
https://www.jianshu.com/p/da1b972e24f2
其实还有很多很多技巧,例如,用生成的样本代替训练集,其实网上的图片验证码大多是采用开源的,稍作修改而已,大多数情况都能被近似生成出来,上述展示的验证码图片不代表任何实际的网站,如有雷同,纯属巧合,该项目只能用于学习和交流用途,不得用于非法用途。
后记
如果文章描述不够详尽或需要技术支持的,可以加群 857149419 咨询,或在开源项目中提issue,很荣幸能为开源社区贡献绵薄之力。
-
PHP实现简单验证码识别,非常详细!
2021-03-26 11:53:15验证码全自动区分计算机和人类的公开图灵测试(英语:Completely Automated Public Turing test to tell Computers and Humans Apart,简称CAPTCHA),俗称验证码,是一种区分用户是计算机和人的公共全自动程序。... -
php制作的简单验证码识别代码
2020-12-18 13:31:11在CAPTCHA测试中,作为服务器的计算机会自动生成一个问题由用户来解答。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。 ... -
完美验证码识别系统v3.20.zip
2019-07-24 11:41:31完美验证码识别系统V3.20 1.增加DLL识别返回方式2和3具体看我的函数.txt里说明,主要是增加一个可以返回识别后的总体信任度.这个值你可以给它个阀值,比如说如果总体信任度小于60,那么你就不提交服务器,直接重新获取... -
国税总局发票查验平台验证码识别方案,识别率达98%
2020-05-07 21:54:57这是一篇含金量很高的干货文章,国家税务总局全国增值税发票查验平台验证码识别方案和具体思路,实验结果测试了200+次,识别率达到98%以上,识别速度的话,CPU大概5-8毫秒左右,模型大概3mb。 -
易语言自动打码验证码服务端带案例
2021-04-20 10:12:44易语言通用验证码识别服务端,用来做接口还是可以的!将127.0.0.1改成自己的服务器IP,或者域名php案例:$rel = file_get_contents('... -
图形验证码识别接口(免费)
2021-10-24 15:38:38本地图片识别 网络图片识别 二、免费api接口 接口地址:http://www.bhshare.cn/imgcode/ 请求类型:post 接口参数: 参数名 类型 是否必需 备注 token String 是 用户标识(token 免费获取:... -
mbus:基于RabbitMQ简单实现验证码识别平台,训练网络模型智能识别图形验证码
2021-05-10 10:58:52基于机器学习Caffe框架,配合RabbitMQ消息队列技术实现图像验证码识别平台 验证码识别服务竞争消费模式,支持集群部署以支撑大流量服务; 经过观察,目前市场上的小平台基本都是这种模式,再优化也是拆分服务,做限... -
干货丨RPA内网验证码识别技巧
2020-07-01 10:24:38那么这个时候针对一些客户端或者网银登录的字符型验证码识别,没办法通过UiBot调用公网环境中的OCR组件进行识别,或者使用需要外网环境下的打码平台来解决。 对于这种内网字符型验证码,目前总结了以下四种解决方案... -
【Python】爬虫:图形验证码识别(一)
2019-05-22 23:05:56【Python】爬虫:图形验证码识别(一) 一, tesseract 安装,以及相关库安装 二, 举个例子,demo -
自动化测试--20验证码识别
2022-04-09 19:51:072)通过第三方网站识别验证码-人工识别 3)通过万能验证码的方式-为了做自动化测试 4)可以屏蔽掉验证码 5)通过cookie跳过登陆 3.人工智能:通过文字识别 1)打开登录页面并截图 2)根据接口说明,模拟请求,把图片... -
Burp Suite —— 验证码识别、切换IP
2021-12-15 10:53:44验证码识别 前言 Burp Suite是一个集成化的渗透测试工具,它集合了多种渗透测试组件,其各个组件之间可灵活配合,可定制化程度极高,正可谓居家旅行杀人越货必备之神器。 但是当遇到各式各样的验证码,防火墙等场景... -
cookie提取:登录后提取在线cookie,更新至服务器或副本至剪切板,为爬虫抓取跳过复杂验证码识别程序
2021-01-30 07:46:31Cookies提取助手的出现,可以通过手工输入验证码,免去程序实现验证码识别的繁琐实现,提取有效可用的Cookie,提供给爬虫抓取程序,实现免验证码爬取。 功能特点 自定义服务器地址(API) 操作简单,页面快捷菜单... -
12306查询验证码识别客户端
2017-12-15 22:56:2312306查询验证码识别客户端 正确率92%以上 用户在选择图片之后 直接把数据发送服务器 服务器返回结果 -
反爬之验证码识别登录 (OCR字符识别)
2021-09-27 14:07:15在当今大数据时代,数据在互联网上的传播和呈现... 众多企业为了保证服务器的正常运转,反爬虫工程师们不得不使出各种各样的技术手段来阻止爬虫工程师们毫无节制地向服务器索取资源,例如JavaScript 混淆、We -
springboot集成了kaptcha验证码后,首次在服务器上访问验证码并且启动缓慢
2020-12-26 16:57:28springboot集成了kaptcha验证码后,首次在服务器上访问验证 SecureRandom实例花费了[612,537]毫秒。 一般来说,在启动后几秒钟内就可以正常访问springboot,但是将其部署到服务器后,访问需要2到6分钟甚至更长的时间... -
利用百度OCR实现验证码自动识别
2021-04-18 14:10:42在爬取网站的时候都遇到过验证码,那么我们有什么方法让程序自动的识别验证码呢?其实网上已有很多打码平台,但是这些都是需要money。但对于仅仅爬取点数据而接入打码平台实属浪费。所以百度免费ocr正好可以利用。... -
CNN深度神经网络实现验证码识别
2020-09-22 22:47:57深度神经网络实现验证码识别 前段时间接到了一个小项目,要做一个验证码的识别,验证码包含数字和英文字母,实现识别的过程用到了CNN网络,最后单个字符的准确率达到90%以上。 准备数据集 登录界面有一个验证码的... -
验证码识别Burp reCAPTCHA插件使用
2019-12-11 21:29:46Burp的reCAPTCHA也可用来识别验证码,github地址:https://github.com/bit4woo/reCAPTCHA,下载相应的jar包添加到burp中,位置在extender-extensions-add下,添加成功后burp模块栏会多出reCAPTCHA一栏,如下图。... -
Python验证码识别 | 源码+通用识别模型
2019-01-30 17:45:50关键词:Python验证码识别,基于CRNN(CNN+Bi-GRU+CTC)实现的验证码识别方案,无论是简单或者复杂的验证码均可一键99%通杀,包含源码和通用识别模型,可秒杀绝大多数验证码。我可以向你们保证,它绝对会是你所见过... -
常用验证码的识别方法
2018-11-13 15:30:14全自动区分计算机和人类的图灵测试(Completely Automated Public Turing test to tell Computers and Humans Apart,简称CAPTCHA),俗称验证码,是一种区分用户是计算机和人的公共全自动程序。验证码的主要目的是...