验证码识别-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 {// 创建URLURL 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 {//云市场分配的密钥Idpublic static final String secretId = "";//云市场分配的密钥Keypublic 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 headersfor (Map.Entry<String, String> entry : headers.entrySet()) {conn.setRequestProperty(entry.getKey(), entry.getValue());}// request bodyMap<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字符串,后续还可以根据需求做进一步的结果处理。
验证码识别-Java版相关推荐
- 12306登录验证码识别(Java版)
懒惰是程序员的第一生产力 源码地址 1 服务器性能差,不要频繁请求(做了熔断保护处理) 2 上传标准图片 3 添加了爬虫爬取验证功能,设置了ajax返回数据的css样式 窝在家里没事干- python ...
- 菜鸟学Java(六)——简单验证码生成(Java版)
转载自 菜鸟学Java(六)--简单验证码生成(Java版) 验证码大家都知道,它的作用也不用我多说了吧.如果不太清楚请参见百度百科中的解释,一般验证码的生成就是随机产生字符(数字.字母或者汉字等) ...
- 人工智能,百度AI人脸识别java版
人工智能,百度AI人脸识别java版 需求:人脸识别登录,人脸就需要有人脸的照片,数据库建一个字段face保存用户人脸的照片,jquery.webcam.js实现调用摄像头拍照,然后后端接受base6 ...
- 京东商城(360Buy)价格识别 java版
上一篇介绍到 利用Jsoup抓取各个电商网站的信息 不过有时候会遇到价格是图片的问题 这时候你只能得到一张图片了 如果有个能把图片解析出来那该多爽啊 去百度一搜"京东(360Buy)价格识别 ...
- 验证码识别 java 深度学习_使用深度学习识别验证码注解
前言 在抓取一些网站的时候难免会遇到一些验证码.想起去年接触过一段时间的验证码识别技术,所以把之前使用的开源的cnn识别再拿出来做个注解.加深理解,也方便以后的使用.希望能对大家有所帮助! 正文 网上 ...
- 滑块验证码识别 java版本
https://blog.csdn.net/qq_19383667/article/details/77879895 好久没有更新技术文章了,很久之前研究过滑块验证码的破解,照着别人的代码改,将其他版 ...
- 滑块验证码识别 java版本
好久没有更新技术文章了,很久之前研究过滑块验证码的破解,照着别人的代码改,将其他版本的代码改成java的,加上自己的一些研究,凑合凑合出了第一个java版本的,此版本不是控制浏览器进行验证,纯java ...
- 菜鸟学Java——简单验证码生成(Java版)
验证码大家都知道,它的作用也不用我多说了吧.如果不太清楚请参见百度百科中的解释,一般验证码的生成就是随机产生字符(数字.字母或者汉字等),然后将这些生成的字符绘制成一张图片,再在图片上加上一些干扰元素 ...
- 国税总局增值税发票查验平台验证码识别深度学习实战
国家税务总局全国增值税发票查验平台验证码 查验验证码图片如下面所示: 测试地址:http://47.99.174.98:8808/ 1.验证码识别Python版 import base64 impor ...
- java版阿里云,百度ai,讯飞语音识别效果简单对比及demo
因为公司的业务的需要,对三家的语音识别(简短语句识别java版)进行了调用和对比,把自己的测试成果贴出来供需要的人参考使用.并贴出主要代码块 阿里云的一句话识别: package com.alibab ...
最新文章
- 从刚入职阿里的学弟那里薅来的面试题,速速领取~~~
- Oracle 内置函数
- android屏幕底部黑块,Android surfaceView 黑块问题
- python免费教学视频教程-Python免费教程_Python免费视频教程大全_易玩网
- PAT甲级1012 The Best Rank :[C++题解]4个成绩取排名最低:排序、二分(好题)
- C++中如何定义某个数组的引用?
- STL容器的线程安全
- 路由器snmp配置_S7503E V7 snmpv3典型组网配置案例(与IMC联动)
- bootstrap4 后台管理模板_开源的后台管理模板
- python美多商城项目百度网盘_美多商城项目(六)
- ACM字符串处理算法经典:字符串搜索
- JS Array创建及concat()split()slice()使用
- linux内核打印%us,linux-kernel-使用us计时器跟踪Linux内核,按功能(仅最大)
- C#中winform怎么在线预览PDF,预览网上的PDF控件!不用安装Adobe PDF Reader等等其他,方案记录
- 小红书账号分析丨千瓜指数高的小红书账号是否真的优质?
- lms语音降噪matlab实现_ANC主动降噪理论及Matlab代码实现
- 微波信号发生器典型应用——TFN TG115 微波信号发生器 100KHz-15GHz
- VSCode删除多余空行快捷方法
- 计算机控制器安装方法,win7正确安装3D视频控制器的两种方法介绍
- Java中数据库的多表操作