前段时间用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版相关推荐

  1. 12306登录验证码识别(Java版)

    懒惰是程序员的第一生产力 源码地址 1 服务器性能差,不要频繁请求(做了熔断保护处理) 2 上传标准图片 3 添加了爬虫爬取验证功能,设置了ajax返回数据的css样式 窝在家里没事干- python ...

  2. 菜鸟学Java(六)——简单验证码生成(Java版)

    转载自  菜鸟学Java(六)--简单验证码生成(Java版) 验证码大家都知道,它的作用也不用我多说了吧.如果不太清楚请参见百度百科中的解释,一般验证码的生成就是随机产生字符(数字.字母或者汉字等) ...

  3. 人工智能,百度AI人脸识别java版

    人工智能,百度AI人脸识别java版 需求:人脸识别登录,人脸就需要有人脸的照片,数据库建一个字段face保存用户人脸的照片,jquery.webcam.js实现调用摄像头拍照,然后后端接受base6 ...

  4. 京东商城(360Buy)价格识别 java版

    上一篇介绍到 利用Jsoup抓取各个电商网站的信息 不过有时候会遇到价格是图片的问题 这时候你只能得到一张图片了 如果有个能把图片解析出来那该多爽啊 去百度一搜"京东(360Buy)价格识别 ...

  5. 验证码识别 java 深度学习_使用深度学习识别验证码注解

    前言 在抓取一些网站的时候难免会遇到一些验证码.想起去年接触过一段时间的验证码识别技术,所以把之前使用的开源的cnn识别再拿出来做个注解.加深理解,也方便以后的使用.希望能对大家有所帮助! 正文 网上 ...

  6. 滑块验证码识别 java版本

    https://blog.csdn.net/qq_19383667/article/details/77879895 好久没有更新技术文章了,很久之前研究过滑块验证码的破解,照着别人的代码改,将其他版 ...

  7. 滑块验证码识别 java版本

    好久没有更新技术文章了,很久之前研究过滑块验证码的破解,照着别人的代码改,将其他版本的代码改成java的,加上自己的一些研究,凑合凑合出了第一个java版本的,此版本不是控制浏览器进行验证,纯java ...

  8. 菜鸟学Java——简单验证码生成(Java版)

    验证码大家都知道,它的作用也不用我多说了吧.如果不太清楚请参见百度百科中的解释,一般验证码的生成就是随机产生字符(数字.字母或者汉字等),然后将这些生成的字符绘制成一张图片,再在图片上加上一些干扰元素 ...

  9. 国税总局增值税发票查验平台验证码识别深度学习实战

    国家税务总局全国增值税发票查验平台验证码 查验验证码图片如下面所示: 测试地址:http://47.99.174.98:8808/ 1.验证码识别Python版 import base64 impor ...

  10. java版阿里云,百度ai,讯飞语音识别效果简单对比及demo

    因为公司的业务的需要,对三家的语音识别(简短语句识别java版)进行了调用和对比,把自己的测试成果贴出来供需要的人参考使用.并贴出主要代码块 阿里云的一句话识别: package com.alibab ...

最新文章

  1. 从刚入职阿里的学弟那里薅来的面试题,速速领取~~~
  2. Oracle 内置函数
  3. android屏幕底部黑块,Android surfaceView 黑块问题
  4. python免费教学视频教程-Python免费教程_Python免费视频教程大全_易玩网
  5. PAT甲级1012 The Best Rank :[C++题解]4个成绩取排名最低:排序、二分(好题)
  6. C++中如何定义某个数组的引用?
  7. STL容器的线程安全
  8. 路由器snmp配置_S7503E V7 snmpv3典型组网配置案例(与IMC联动)
  9. bootstrap4 后台管理模板_开源的后台管理模板
  10. python美多商城项目百度网盘_美多商城项目(六)
  11. ACM字符串处理算法经典:字符串搜索
  12. JS Array创建及concat()split()slice()使用
  13. linux内核打印%us,linux-kernel-使用us计时器跟踪Linux内核,按功能(仅最大)
  14. C#中winform怎么在线预览PDF,预览网上的PDF控件!不用安装Adobe PDF Reader等等其他,方案记录
  15. 小红书账号分析丨千瓜指数高的小红书账号是否真的优质?
  16. lms语音降噪matlab实现_ANC主动降噪理论及Matlab代码实现
  17. 微波信号发生器典型应用——TFN TG115 微波信号发生器 100KHz-15GHz
  18. VSCode删除多余空行快捷方法
  19. 计算机控制器安装方法,win7正确安装3D视频控制器的两种方法介绍
  20. Java中数据库的多表操作

热门文章

  1. 被历史遗忘的第一骑兵名将 —— 陈庆之
  2. JAVA从入门到精通(2)
  3. 冬天,这6款养生粥,你是一定要喝的
  4. 第十三周作业-必做3
  5. 2021-5-1 【PTA】【L1-6 不变初心数 (15 分)】
  6. 高德地图api的自定义地点标注
  7. java八皇后答案_java八皇后问题详解
  8. Mocha.js官方文档翻译 —— 简单、灵活、有趣
  9. python火车票票价_python的requests库爬取火车票信息和所需价钱
  10. FairGuard游戏加固兼容摸摸鱼和TAPTAP云玩