精华内容
下载资源
问答
  • 使用java来做验证码识别识别一些普通的验证码图片 前言: 我们都知道,验证码的作用是用来验证你是否为机器人,基本是做反爬虫或刷数据的一类功能验证。针对这种情况,引用一位老人家的名言,“要用魔法打败魔法”...

    使用java来做验证码识别,识别一些普通的验证码图片

    最近公司要做爬虫
    前言:
    我们都知道,验证码的作用是用来验证你是否为机器人,基本是做反爬虫或刷数据的一类功能验证。针对这种情况,引用一位老人家的名言,“要用魔法打败魔法”,我们想爬别人数据只能通过更高明的技术。本文介绍的也不是啥高明的手段,毕竟只能识别一些简单的验证码,废话少说,直接上干货。

    思路分析:
    代码并不是我原创的,我只是一个裁缝,把别人的布自己拼一拼,再用点自己的线。验证码区分是否是机器和真人的方式就是在图片上加上一些干扰线,干扰机器的识别。

    示例图片:
    在这里插入图片描述
    这些杂线干扰了机器的识别,BAT提供的云服务ocr识别不了。我们需要进行格式化,通过代码的操作后生成的图片为
    在这里插入图片描述
    去掉了干扰线以后在使用orc识别准确率基本到80%~90%了。但是机器容易自动识别出一些空格,有的杂线没有完全去除,导致识别出"、"," ` "等各种字符(例如示例验证码R下的、),所以我加了字符的过滤,只留下字母和数字。也有一些J会识别成 ] ,所以在过滤之前加一下判断,这个需要自己来加,我没有加。

    ocr识别是引入的一个jar包,有防爬虫执行,识别几次后让你点击才能继续执行。针对这点可以把免费的jar包换位云服务的识别接口。

    首先引入pom依赖

    <!-- 获取并识别验证码-->
            <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.15</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.8.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient -->
            <dependency>
                <groupId>commons-httpclient</groupId>
                <artifactId>commons-httpclient</artifactId>
                <version>3.1</version>
            </dependency>
            <dependency>
                <groupId>com.asprise.ocr</groupId>
                <artifactId>java-ocr-api</artifactId>
                <version>15.3.0.3</version>
            </dependency>
    

    然后是工具类,工具类有两个方法,

    package com.evaluation.train.common.util;
    
    
    import com.asprise.ocr.Ocr;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpStatus;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.io.IOUtils;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;
    import java.util.Date;
    
    public class OCRCodeUtil {
        /**
         *  根据接口地址识别
         * @param netPath http链接
         * @param savePath 验证码图片保存到本地的位置
         * @param destDir 验证码可识别操作后的保存位置
         * @return
         * @throws IOException
         */
        public static String DictCode(String netPath, String savePath, String destDir) throws IOException {
            //把文件保存到本地地址
            HttpClient httpClient = new HttpClient();
            GetMethod getMethod = new GetMethod(netPath);
            int statusCode = httpClient.executeMethod(getMethod);
            if (statusCode != HttpStatus.SC_OK) {
                System.err.println("Method failed: " + getMethod.getStatusLine());
                return "Method failed: " + getMethod.getStatusLine();
            }
            String picName = savePath;
            File filepic = new File(picName);
            if (!filepic.exists())
                filepic.mkdir();
            String fileName = picName + new Date().getTime() + ".jpg";
            File filepicF = new File(fileName);
            InputStream inputStream = getMethod.getResponseBodyAsStream();
            OutputStream outStream = new FileOutputStream(filepicF);
            IOUtils.copy(inputStream, outStream);
            outStream.close();
            filepicF = new File(fileName);
            cleanLinesInImage(filepicF, destDir);
            Ocr.setUp(); // one time setup
            Ocr ocr = new Ocr(); // create a new OCR engine
            ocr.startEngine("eng", Ocr.SPEED_FASTEST); // English
            String code = ocr.recognize(new File[]{filepicF}, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
    //        char[] chars = code.toCharArray();
    //        for (int i = 0; i < chars.length; i++) {
    //            switch (chars[i]) {
    //                case ']':
    //                    chars[i] = 'j';
    //                    break;
    //            }
    //        }
    //        code = chars.toString();
            code = code.replaceAll("[^0-9a-zA-Z]", "");
            ocr.stopEngine();
            return code;
    
        }
    
        /**
         * 根据本地路径识别
         *
         * @param sfile   识别的file
         * @param destDir 处理后放入的文件夹
         * @return
         * @throws IOException
         */
        public static String DictCode(File sfile, String destDir) throws IOException {
            cleanLinesInImage(sfile, destDir);
            File filepicF = new File(destDir + sfile.getName());
            Ocr.setUp(); // one time setup
            Ocr ocr = new Ocr(); // create a new OCR engine
            ocr.startEngine("eng", Ocr.SPEED_FASTEST); // English
            String code = ocr.recognize(new File[]{filepicF}, Ocr.RECOGNIZE_TYPE_TEXT, Ocr.OUTPUT_FORMAT_PLAINTEXT);
    //        char[] chars = code.toCharArray();
    //        for (int i = 0; i < chars.length; i++) {
    //            switch (chars[i]) {
    //                case ']':
    //                    chars[i] = 'j';
    //                    break;
    //            }
    //        }
    //        code = chars.toString();
            code = code.replaceAll("[^0-9a-zA-Z]", "");
            ocr.stopEngine();
            return code;
    
        }
    
        /**
         * @param sfile   需要去噪的图像
         * @param destDir 去噪后的图像保存地址
         * @throws IOException
         */
        public static void cleanLinesInImage(File sfile, String destDir) throws IOException {
            File destF = new File(destDir);
            if (!destF.exists()) {
                destF.mkdirs();
            }
    
            BufferedImage bufferedImage = ImageIO.read(sfile);
            int h = bufferedImage.getHeight();
            int w = bufferedImage.getWidth();
    
            // 灰度化
            int[][] gray = new int[w][h];
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    int argb = bufferedImage.getRGB(x, y);
                    // 图像加亮(调整亮度识别率非常高)
                    int r = (int) (((argb >> 16) & 0xFF) * 1.1 + 30);
                    int g = (int) (((argb >> 8) & 0xFF) * 1.1 + 30);
                    int b = (int) (((argb >> 0) & 0xFF) * 1.1 + 30);
                    if (r >= 255) {
                        r = 255;
                    }
                    if (g >= 255) {
                        g = 255;
                    }
                    if (b >= 255) {
                        b = 255;
                    }
                    gray[x][y] = (int) Math
                            .pow((Math.pow(r, 2.2) * 0.2973 + Math.pow(g, 2.2)
                                    * 0.6274 + Math.pow(b, 2.2) * 0.0753), 1 / 2.2);
                }
            }
    
            // 二值化
            int threshold = ostu(gray, w, h);
            BufferedImage binaryBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    if (gray[x][y] > threshold) {
                        gray[x][y] |= 0x00FFFF;
                    } else {
                        gray[x][y] &= 0xFF0000;
                    }
                    binaryBufferedImage.setRGB(x, y, gray[x][y]);
                }
            }
    
            //去除干扰线条
            for (int y = 1; y < h - 1; y++) {
                for (int x = 1; x < w - 1; x++) {
                    boolean flag = false;
                    if (isBlack(binaryBufferedImage.getRGB(x, y))) {
                        //左右均为空时,去掉此点
                        if (isWhite(binaryBufferedImage.getRGB(x - 1, y)) && isWhite(binaryBufferedImage.getRGB(x + 1, y))) {
                            flag = true;
                        }
                        //上下均为空时,去掉此点
                        if (isWhite(binaryBufferedImage.getRGB(x, y + 1)) && isWhite(binaryBufferedImage.getRGB(x, y - 1))) {
                            flag = true;
                        }
                        //斜上下为空时,去掉此点
                        if (isWhite(binaryBufferedImage.getRGB(x - 1, y + 1)) && isWhite(binaryBufferedImage.getRGB(x + 1, y - 1))) {
                            flag = true;
                        }
                        if (isWhite(binaryBufferedImage.getRGB(x + 1, y + 1)) && isWhite(binaryBufferedImage.getRGB(x - 1, y - 1))) {
                            flag = true;
                        }
                        if (flag) {
                            binaryBufferedImage.setRGB(x, y, -1);
                        }
                    }
                }
            }
    
    
            // 矩阵打印
    //        for (int y = 0; y < h; y++) {
    //            for (int x = 0; x < w; x++) {
    //                if (isBlack(binaryBufferedImage.getRGB(x, y))) {
    //                    //System.out.print("*");
    //                } else {
    //                    //System.out.print(" ");
    //                }
    //            }
    //            //System.out.println();
    //        }
            ImageIO.write(binaryBufferedImage, "jpg", new File(destDir, sfile
                    .getName()));
        }
    
        public static boolean isBlack(int colorInt) {
            Color color = new Color(colorInt);
            if (color.getRed() + color.getGreen() + color.getBlue() <= 300) {
                return true;
            }
            return false;
        }
    
        public static boolean isWhite(int colorInt) {
            Color color = new Color(colorInt);
            if (color.getRed() + color.getGreen() + color.getBlue() > 300) {
                return true;
            }
            return false;
        }
    
        public static int isBlackOrWhite(int colorInt) {
            if (getColorBright(colorInt) < 30 || getColorBright(colorInt) > 730) {
                return 1;
            }
            return 0;
        }
    
        public static int getColorBright(int colorInt) {
            Color color = new Color(colorInt);
            return color.getRed() + color.getGreen() + color.getBlue();
        }
    
        public static int ostu(int[][] gray, int w, int h) {
            int[] histData = new int[w * h];
            // Calculate histogram
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    int red = 0xFF & gray[x][y];
                    histData[red]++;
                }
            }
    
            // Total number of pixels
            int total = w * h;
    
            float sum = 0;
            for (int t = 0; t < 256; t++)
                sum += t * histData[t];
    
            float sumB = 0;
            int wB = 0;
            int wF = 0;
    
            float varMax = 0;
            int threshold = 0;
    
            for (int t = 0; t < 256; t++) {
                wB += histData[t]; // Weight Background
                if (wB == 0)
                    continue;
    
                wF = total - wB; // Weight Foreground
                if (wF == 0)
                    break;
    
                sumB += (float) (t * histData[t]);
    
                float mB = sumB / wB; // Mean Background
                float mF = (sum - sumB) / wF; // Mean Foreground
    
                // Calculate Between Class Variance
                float varBetween = (float) wB * (float) wF * (mB - mF) * (mB - mF);
    
                // Check if new maximum found
                if (varBetween > varMax) {
                    varMax = varBetween;
                    threshold = t;
                }
            }
    
            return threshold;
        }
    }
    
    
    展开全文
  • 这种方案对验证码的处理相对较少,运用相对普遍,很多验证码图片可以通过这个方式得到识别,当然还需要一部分的降噪处理。什么是图片二值化处理:简单也就是把一张五颜六色的验证码处理成一张只由黑白构成的验证码,...

    Python中有专门的图像处理技术比如说PIL,可以对验证码一类的图片进行二值化处理,然后对图片进行分割,进行像素点比较得到图片中的数字。这种方案对验证码的处理相对较少,运用相对普遍,很多验证码图片可以通过这个方式得到识别,当然还需要一部分的降噪处理。

    什么是图片二值化处理:简单也就是把一张五颜六色的验证码处理成一张只由黑白构成的验证码,这个是为了方便后期我们和保存的黑白单一数字、字母进行像素点比较。

    什么是降噪处理:简单的解释就是把验证码中的干扰去掉一部分,降噪不可能完全降,但是可以处理一大部分就是对识别的一种进步,毕竟如果降噪处理不行,对后期的像素点比较和结果值影响比较大。

    今天我们用图片的RGB的色彩比对技术,用JAVA对图片进行一次二值化处理,然后识别。

    原图片:

    831a39865f6bc5635416eb645a174887.png

    二值化后图片:

    f63e7088a556990eb154376dab9bb870.png

    我们针对这个网页的验证码需要在自己库中保存的模板类型:

    b6ea08c1116643084a473d4b4fcfcc22.png

    1f96211b39446ea2f2d4b680e4d21c67.png.....这一类是用于后期像素点比较得到图片本身数值的准备。

    那么基本流程我们知道了,我们就开始

    第一步:图片下载:

    网页的抓取有时候会有验证码的识别,这样我们就需要对http请求的包进行解析,有的验证码可以在js中解析得到,有的是直接返回该网页页面,反正可以找到这个img图片进行下载到本地就行,此处不一一赘述。

    第二部:对下载到本地的图片进行二值化处理:

    在这里我自己写了一个脚本,供大家使用和参考:

    public class MyImgDel {

    //todo splitNums可以根据你给到的图片色差进行调整,在你自己使用时,可以针对splitNums做一个循环,每次加多少,得到不同的色差比的二值化后的图片,因为不同的图片可能干扰线、干扰点颜色原因,二值化后会有差异

    //todo splitWidthNum:把图片根据长度切分的分数,这个可以根据你图片中的数字个数进行切分

    public static final int splitNums=4000000;

    public static final int splitWidthNum=5;

    public static void main(String[] args) {

    String path="F://test1.png";

    try{

    BufferedImage img=removeBackgroud(path);

    ImageIO.write(img, "PNG", new File("F://test1-1.png"));

    }catch (Exception e){

    e.printStackTrace();

    }

    }

    public static BufferedImage removeBackgroud(String picFile)

    throws Exception {

    BufferedImage img = ImageIO.read(new File(picFile));

    img = img.getSubimage(1, 1, img.getWidth()-2, img.getHeight()-2);

    int width = img.getWidth();

    int height = img.getHeight();

    double subWidth = (double) width/(splitWidthNum+0.0);

    Map map = new HashMap();

    for (int i = 0; i < splitWidthNum; i++) {

    //todo 以下是对图片进行二值化处理,在这里我的思路是规定,色差范围在splitNums到负splitNums之间的,算是同色,放入同一个色值,放入一个map中,map中的Key放色值,value放这个色值得个数,后期就根据这个色值来对验证码进行二值化

    for (int x = (int) (1 + i * subWidth); x < (i + 1) * subWidth && x < width - 1; ++x) {

    for (int y = 0; y < height; ++y) {

    if (isWhite(img.getRGB(x, y)) == 1){

    continue;

    }

    Map map2 = new HashMap();

    for (Integer color : map.keySet()) {

    map2.put(color,map.get(color));

    }

    for (Integer color : map2.keySet()) {

    System.out.println(Math.abs(color)-Math.abs(img.getRGB(x, y)));

    if (Math.abs(color)-Math.abs(img.getRGB(x, y))-splitNums){

    map.put(color, map.get(color) + 1);

    }else{

    map.put(img.getRGB(x, y), 1);

    }

    }

    if (map.isEmpty()){

    map.put(img.getRGB(x, y), 1);

    }

    }

    }

    System.out.println("==============================");

    int max = 0;

    int colorMax = 0;

    for (Integer color : map.keySet()) {

    if (max < map.get(color)) {

    max = map.get(color);

    colorMax = color;

    }

    }

    for (int x = (int) (1 + i * subWidth); x < (i + 1) * subWidth&& x < width - 1; ++x) {

    for (int y = 0; y < height; ++y) {

    int ress=Math.abs(img.getRGB(x, y))-Math.abs(colorMax);

    if (ress-splitNums) {

    img.setRGB(x, y, Color.WHITE.getRGB());

    } else {

    img.setRGB(x, y, Color.BLACK.getRGB());

    }

    }

    }

    }

    return img;

    }

    //todo 判断是否为白色的方法

    public static int isWhite(int colorInt) {

    Color color = new Color(colorInt);

    if (color.getRed() + color.getGreen() + color.getBlue()>600) {

    return 1;

    }

    return 0;

    }

    }

    处理到这里我们就可以得到一个二值化后的图片了。

    然后我们就要开始对二值化后的图进行等分,然后和我们样本库中的图片进行一次像素比对。

    展开全文
  • 原创 野狗菌 希望你能喜欢 今天关于本文:本文介绍一个简单Java爬虫,获取网页源码,爬取电话号码。本篇教程用我的博客一个测试网页演示。——野狗菌【希望你能喜欢】测试页面:...

    原创 野狗菌 希望你能喜欢 今天

    关于本文:

    本文介绍一个简单Java爬虫,获取网页源码,爬取电话号码。

    本篇教程用我的博客一个测试网页演示。

    ——野狗菌【希望你能喜欢】

    测试页面:

    https://www.wayteam.xyz/archives/phonenumber

    源代码:(注释写的很详细了,太艰难,就直接放代码,不做多解释了)

    import java.io.*;

    import java.net.URL;

    import java.net.URLConnection;

    import java.util.regex.Matcher;

    import java.util.regex.Pattern;

    /**

    * @author 野狗菌

    * 2020-04-06

    * 爬虫入门(一):获取网页源代码,爬取手机号码

    * 微信公众号:希望你能喜欢 (也可以搜索 foryouway )

    * 个人网站:www.wayteam.xyz

    */

    public class GetPhoneNumber {

    public static void main(String[] args) throws Exception {

    //创建一个要访问的url

    URL url = new URL("https://www.wayteam.xyz/archives/phonenumber");//这里以我的博客测试页面为例

    System.out.println("正在获取"+url+"网站的手机号码中-----请稍等");//无关紧要的代码,只是为了友好的提示

    //打开上面获取的链接

    URLConnection urlConnection = url.openConnection(); //新手提醒:这个会抛出异常,我为了方便,全部抛出去,不作处理throws Exception

    //创建一个指定的存储文件

    File file = new File("phone.txt"); //这里是相对路径,表示存在这个同级目录下

    //创建一个字符输出流(从本程序输出到phone.txt文件)

    PrintWriter printWriter = new PrintWriter(file);//程序执行到这里就会在对应位置创建对应文件了

    //创建一个输入流(这个输入输出是以本程序为参照)

    InputStream inputStream = urlConnection.getInputStream();

    //把上面的字节流转化为字符流

    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

    //把字符流转化为字符缓冲流

    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

    //创建一个空的字符串来接收从字符缓冲流里接收的数据

    String htmlLine = null;

    //手机号码的正则表达式,用来匹配数据中的手机号码

    String regex = "1[35789]\\d{9}";//1:第一位是1,[35789]:第二位是35789中的一个,\d{9}:剩余9位数任意(因为java中\需要转义,所以这里用\\)。

    Pattern pattern = Pattern.compile(regex);//把正则表达式编译成模式。

    //用while遍历上面的到的字缓冲流,把值给上面的空字符串(readLine是一行一行读取网页源代码的)

    while ((htmlLine = bufferedReader.readLine()) != null){ //当字符流缓冲流没有为空时,一直读取它。

    //创建一个匹配器来匹配上面的正则表达式模式

    Matcher matcher = pattern.matcher(htmlLine);

    //循环匹配

    while (matcher.find()){ //当匹配成功时,往下执行

    printWriter.println(matcher.group());//将匹配的数据用group转化为字符串,写进字符输出流中

    }

    /**

    * 在控制台打印htmlLine,观察它是什么样的数据

    * 为了方便大家理解readLine执行过程,给进程设置一个休眠时间,不然数据哗啦一下直接出来

    * 这里我录制了一个动图,大家也可以自己试试。

    */

    /*System.out.println(htmlLine);

    Thread.sleep(100);//100毫秒*/

    }

    /**

    * 关闭这两个流

    */

    bufferedReader.close();

    printWriter.close();

    System.out.println("获取号码成功,快去"+file+"查看结果吧"+"\n"+"-------by野狗菌\uD83D\uDC36");//无关紧要的代码,只是为了友好的提示

    }

    }

    一个演示:

    结果展示:

    问题:为什么这里获取的手机号码比我网页里面写的要多?

    因为这些数据被我的匹配器匹配成号码了。。。。

    后面会介绍其他抓取方式,可以避免这个问题。

    ** **

    ** **

    ** **

    在公众号内发送【07】,即可获取源码(你也可以直接自己创建项目,把上面内容写进去)。

    展开全文
  • 资源包括Java代码以及引用包、tesseract安装包和使用说明
  • ##Java爬虫(获取验证码爬取网页信息) 用到了图片解析Test4j需要下载tessdata maven pom.xml &amp;amp;lt;dependencies&amp;amp;gt; &amp;amp;lt;dependency&amp;amp;gt; &amp;amp...

    Java爬虫(获取验证码爬取网页信息) 用到了图片解析Test4j需要下载tessdata

    maven pom.xml

     <dependencies>
      		<dependency>
     		   <groupId>org.apache.httpcomponents</groupId>
        	   <artifactId>httpclient</artifactId>
            <version>4.5.6</version>
            </dependency>
    		<dependency>
    		    <groupId>org.jsoup</groupId>
    		    <artifactId>jsoup</artifactId>
    		    <version>1.11.3</version>
    		</dependency>
    		<dependency>
    		    <groupId>net.sf.json-lib</groupId>
    		    <artifactId>json-lib</artifactId>
    		    <version>2.0</version>
    		   <classifier>jdk15</classifier>
    		</dependency>
    		 <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.15-beta2</version>
            </dependency>
     
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.15-beta2</version>
            </dependency>
           <dependency>
                <groupId>net.java.dev.jna</groupId>
                <artifactId>jna</artifactId>
                <version>4.1.0</version>
            </dependency>
            <dependency>
                <groupId>net.sourceforge.tess4j</groupId>
                <artifactId>tess4j</artifactId>
                <version>2.0.1</version>
                <exclusions>
                    <exclusion>
                        <groupId>com.sun.jna</groupId>
                        <artifactId>jna</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    		<dependency>
    		    <groupId>org.apache.httpcomponents</groupId>
    		    <artifactId>httpclient</artifactId>
    		    <version>4.3.6</version>
    		</dependency>
    		 <dependency>
    		  <groupId>net.sourceforge.tess4j</groupId> 
    		  <artifactId>tess4j</artifactId> 
    		  <version>3.2.1</version> 
    		</dependency>
    		<dependency>
    		   <groupId>ch.qos.logback</groupId>
    		   <artifactId>logback-classic</artifactId>
    		   <version>1.2.3</version>
    		</dependency>
    		<dependency>
    		   <groupId>ch.qos.logback</groupId>
    		   <artifactId>logback-core</artifactId>
    		   <version>RELEASE</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.json</groupId>
    		    <artifactId>json</artifactId>
    		    <version>20180130</version>
    		</dependency>
      </dependencies>
    

    创建一个PictureAddressUtil工具类 获取图片地址

    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    public class PictureAddressUtil {
    	
    	public List<String> filePath(String content) {
    		List<String> srcList = new ArrayList<String>(); //用来存储获取到的图片地址
    		Pattern p = Pattern.compile("<(img|IMG)(.*?)(>|></img>|/>)");//匹配字符串中的img标签
    		Matcher matcher = p.matcher(content);
    		boolean hasPic = matcher.find();
    		if(hasPic == true)//判断是否含有图片
    		{
    			while(hasPic) //如果含有图片,那么持续进行查找,直到匹配不到
    			{
    				String group = matcher.group(2);//获取第二个分组的内容,也就是 (.*?)匹配到的
    				Pattern srcText = Pattern.compile("(src|SRC)=(\"|\')(.*?)(\"|\')");//匹配图片的地址
    				Matcher matcher2 = srcText.matcher(group);
    				if( matcher2.find() ) 
    				{
    					srcList.add( matcher2.group(3) );//把获取到的图片地址添加到列表中
    				}
    				hasPic = matcher.find();//判断是否还有img标签
    			}		
    		}
    		return srcList;
    	}
    }
    
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URI;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.commons.io.IOUtils;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.CookieStore;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    
    import net.sf.json.JSONArray;
    import net.sf.json.JSONObject;
    import net.sourceforge.tess4j.ITesseract;
    import net.sourceforge.tess4j.Tesseract;
    import net.sourceforge.tess4j.TesseractException;
    public class HuaNanShiFanStudent {
    	
    	public static void main(String[] args) throws Exception {
    		  String name = "学生信息列表";
    		  // 创建excel
    	      HSSFWorkbook wk = new HSSFWorkbook();
    	       // 创建一张工作表
    	       HSSFSheet sheet = wk.createSheet();
    	       // 2
    	       sheet.setColumnWidth(0, 5000);
    	       HSSFRow row = sheet.createRow(0);
    	       // 创建第一行的第一个单元格
    	       // 想单元格写值
    	       HSSFCell cell = row.createCell((short) 0);
    	       cell.setCellValue("学号");
    	       cell = row.createCell((short)1);
    	       cell.setCellValue("姓名");
    	       
    	       HuaNanShiFanStudent fanStudent = new HuaNanShiFanStudent();
    	       List<TR>  trs =  fanStudent.HuaNanShiFanStudent_List();
    	       for (int i=0;i<trs.size();i++) {
    	    	   row = sheet.createRow(i+1);
    	    	   row.createCell(0).setCellValue(trs.get(i).getTd0());
    	    	   row.createCell(1).setCellValue(trs.get(i).getTd1()); 
    	       }
    	       wk.write(new FileOutputStream(new File("C:\\Users\\啊\\Desktop\\"+name+".xls")));
             wk.close();
    	      System.out.println("运行成功");
    	}
    	
    	
    	
    	
    	 public List<TR> HuaNanShiFanStudent_List() throws Exception {
    		 List<TR> trs = new ArrayList<TR>(); 
    		//用来存取cookies信息的变量
    	    	CookieStore store;
    	         /**
    	          * 请求第一次页面
    	          */
    	    	//第一次请求(登陆的请求)
    	    	DefaultHttpClient client1 = new DefaultHttpClient();
    	        HttpPost request1 = new HttpPost("http://www.baidu.com/");
    	        store = client1.getCookieStore();
    	        HttpResponse response1 = client1.execute(request1);  
    	        if (response1.getStatusLine().getStatusCode() == 200) {  
    	        	HttpEntity entity1 = response1.getEntity();
    	        	//获取
    	            String result1 = EntityUtils.toString(entity1); 
    	          
    	            //使用jsoup 进行语言转换
    	            Document doc1 = Jsoup.parse(result1);
    	           //获取table表格
    	        	String string = doc1.getElementById("imgCode").toString();
    	          
    	       
    	           //爬取验证码  图片/sso/authimg
    	           PictureAddressUtil addressUtil = new PictureAddressUtil();
    	           List<String> list = addressUtil.filePath(string);
    	        	
    	           /**
    	            * 通过验证码   下载下来   并用tess4j图片识别其中的验证码
    	            */
    	           DefaultHttpClient client2 = new DefaultHttpClient();
    	           HttpPost request2 = new HttpPost("http://www.baidu.com/"+list.get(0)+""); 
    	           client2.setCookieStore(store);
    		        HttpResponse response2 = client2.execute(request2);  
    	            downloadJPG(response2,"1.jpg");
    	   		    String code = getImgContent("1.jpg");
    	   		    
    	   		    System.out.println("验证码 = " + code);
    	            System.out.println("==============================="); 
    	   		    /**
    	   		     * 登录请求
    	   		     */
    	   		    DefaultHttpClient client3 = new DefaultHttpClient();
    	            HttpPost request3 = new HttpPost("http://www.baidu.com?username=用户名&password=密码&authCode="+验证码+"");
    	            client3.setCookieStore(store);
    	            HttpResponse response3 = client3.execute(request3);  
    	            if (response3.getStatusLine().getStatusCode() == 200) {  
    	            	HttpEntity entity3 = response3.getEntity();
    	            	//获取
    	                String result3 = EntityUtils.toString(entity3);
    	               
    	                System.out.println("Response content: " + result3);  
    	                System.err.println("===============================");
    	                
    	              /**
    	               * 请求
    	               */
    	                DefaultHttpClient client4 = new DefaultHttpClient();
    		            HttpPost request4 = new HttpPost("接口");       
    		            client4.setCookieStore(store);
    		            HttpResponse response4 = client4.execute(request4);  
    		            if (response4.getStatusLine().getStatusCode() == 200) {  
    		                
    		            	HttpEntity entity4 = response4.getEntity();
    		            	//获取
    		                String json4 = EntityUtils.toString(entity4); 
    		              /* System.err.println("===============================");  
    		                System.out.println("Response content: " + json4);  
    		                System.out.println("===============================");  */
    		             //  JSONArray jsonArray4 = new JSONArray();
    		                JSONObject jsonObject = JSONObject.fromObject(json4);
    		               
    		                // System.out.println(str);   
    		                int totalCount = Integer.parseInt(jsonObject.getString("totalCount"));
    		                System.out.println("totalCount========"+totalCount);
    		                
    		                
    		              //循环查询的次数
    		            	int Index ;
    		            	int  remaInder = totalCount%1000;
    		            	if(remaInder>0) {
    		            		Index = (totalCount/1000)+1;
    		            	}else {
    		            		Index = totalCount/1000;
    		            	}
    		            	if(Index>0) {
    		            		DefaultHttpClient client5 = new DefaultHttpClient();
    		            		HttpPost request5 = new HttpPost();
    		            	    int start = 0;
    		            	    int limit = 1000;
    		  	                
    		  	              for (int n = 0; n < Index; n++) {
    		  	            	  System.out.println(n);
    		  	            	request5.setURI(new URI( "http://www.baidu.com?&start="+start+"&limit="+limit+"&sort=id&dir=DESC"));       
    		  		            client5.setCookieStore(store);
    		  		            HttpResponse response5 = client5.execute(request5);  
    		  		            if (response5.getStatusLine().getStatusCode() == 200) {  
    		  		                
    		  		            	HttpEntity entity5 = response5.getEntity();
    		  		            	//获取
    		  		                String json5 = EntityUtils.toString(entity5); 
    		  		                JSONObject jsonObject5 = JSONObject.fromObject(json5);
    		                
    		                        JSONArray data = jsonObject5.getJSONArray("models");
    		               
    		                  
    		                    for (int i = 0; i<data.length();i++){
    		                        JSONObject jsonObject10 = data.getJSONObject(i);
    		                        String regNo = jsonObject10.getString("regNo");
    		                        String trueName = jsonObject10.getString("trueName");
    		                        String cardNo = jsonObject10.getJSONObject("prStudentInfo").getString("cardNo");
    		                        String genderNanme =  jsonObject10.getJSONObject("prStudentInfo").getString("gender");
    		                        String peSite = jsonObject10.getJSONObject("peSite").getString("name");
    		                        String peGrade = jsonObject10.getJSONObject("peGrade").getString("name");
    		                        String peMajor = jsonObject10.getJSONObject("peMajor").getString("name");
    		                        String peEdutype = jsonObject10.getJSONObject("peMajor").getString("name");
    		                        String enumConstByFlagMajorType = jsonObject10.getJSONObject("enumConstByFlagMajorType").getString("name");//
    		                        String enumConstByFlagStudentStatus = jsonObject10.getJSONObject("enumConstByFlagStudentStatus").getString("name");
     
    		                        
    		                        TR tr = new TR();
    		                        tr.setTd0(regNo);
    		                        tr.setTd1(trueName);
    		                        tr.setTd2(cardNo);
    		                        tr.setTd3(genderNanme);
    		                        tr.setTd4(peSite);
    		                        tr.setTd5(peGrade);
    		                        tr.setTd6(peMajor);
    		                        tr.setTd7(peEdutype);
    		                        tr.setTd8(enumConstByFlagMajorType);
    		                        tr.setTd9(enumConstByFlagStudentStatus);
    		                        trs.add(tr);
    		                       //System.out.println(trueName + peGradeName + peEdutypeNanme + peMajorName + inputDate + feeAmount);
    		                    }
    		            	
    		  		            }
    		  		          start=start+1000; 
    		  		            
    		  	              }
    		  	              }
    		            }
    	                
    	            }
    	   		   
    	         }
    			return trs;
    		
    		} 
    		
    	
    	public static void downloadJPG(HttpResponse httpResponse,String fileName) throws IOException {
    		InputStream input = httpResponse.getEntity().getContent();
    		OutputStream output = new FileOutputStream(new File(fileName));
    		IOUtils.copy(input, output);
    		if (output != null) {
    		output.close();
    		}
    		output.flush();
    		}
    	public static String getImgContent(String imgUrl) {
    		String content = "";
    		File imageFile = new File(imgUrl);
    		//读取图片数字
    		ITesseract instance = new Tesseract();
            instance.setDatapath("C:\\Program Files (x86)\\Tesseract-OCR\\tessdata");
    		//File tessDataFolder = LoadLibs.extractTessResources();
    		//C:\Users\啊\AppData\Local\Temp\tess4j\tessdata
    		instance.setLanguage("chi_sim");//英文库识别数字比较准确
    		//instance.setDatapath(tessDataFolder.getAbsolutePath());
    		try {
    		content = instance.doOCR(imageFile).replace("\n", "");
    		System.out.println(content);
    		} catch (TesseractException e) {
    		System.err.println(e.getMessage());
    		}
    		return content;
    		}
    		
    
    }
    
    展开全文
  • http://jx.189.cn/public/v4/common/control/page/image.jsp?date=&y7bRbP=gfThrac_X.j_X.j_X.cv8nSYNbnPZjEjl62SJullzFgqqhL 这是要爬取的地址,使用postman发送请求,发现必须有cookie: !... 以及要携带一个参数: ...
  • 最近就专门研究这个爬虫问题:1.简单单页网页的爬取2.翻页网页的爬取(商品,新闻类啊)3.需要登陆网页的爬取4.需要登陆加验证的网页爬取5.scrapy 的框架问题6.beautifulSoup、requests7.cookeis、表单数据的查看以上...
  • Java 爬虫识别图片验证码后登录

    千次阅读 热门讨论 2020-01-10 15:07:22
    这几年Python爬虫特别的火,我有个朋友是一个Python爬虫工程师,本人菜鸡Java开发工程师一名,最近所做的一个项目是需要去爬一个网页的数据,但是进入网页需要登录,登录需要输入图片验证码爬虫的第三方jar包用的...
  • 本文含3321字,9代码片段建议阅读8分钟前言在我们写爬虫的过程中,目标网站常见的干扰手段就是设置验证码等,本就将基于Selenium实战讲解如何处理弹窗和验证码,爬取的目标网站为某仪器预约平台 可以看到登录所需的...
  • java解析图片验证码

    热门讨论 2014-01-20 10:31:13
    java解析图片验证码
  • 网络爬虫中的验证码识别

    千次阅读 2017-09-26 20:35:54
    但对于每页都有的,这种方式就不能够解决了,最简单的方式,是自动识别验证码,如果验证码识别成功,能过获得数据,则进行解析,如果验证码没办法识别,则刷新一次验证码,继续识别,直到识别验证码成功,并获得数据...
  • 爬虫实战系列(三):验证码识别

    千次阅读 多人点赞 2020-07-29 20:50:56
    爬虫过程中,我们可能会遇到需要输入验证码的情况,因此验证码也是爬虫的一个壁垒。下面我将介绍如何利用pytesseract模块来进行简单图形验证码识别。 一.验证码图片说明 首先,我在某高校爬取了若干的图形验证码...
  • 滑块验证码识别 java版本

    万次阅读 2017-09-07 12:36:31
    好久没有更新技术文章了,很久之前研究过滑块验证码的破解,照着别人的代码改,将其他版本的代码改成java的,加上自己的一些研究,凑合凑合出了第一个java版本的,目前都完成了,只是滑动轨迹的生成被后台识别出是...
  • 在抓取网站过程中难免碰到图片验证码的问题,要想识别验证码,可以采取机器学习的相关算法,如svm,knn,卷积神经网络等来识别破解验证码,今天我来分享一个能极大提高验证码识别率的操作,去除验证码中的噪点。...
  • Java实现超简单验证码识别

    万次阅读 2018-06-09 23:03:49
    闲来想实现程序模拟登陆一个系统,说白了,就是写个简单的爬虫,但是无奈,遇到了数字图片验证码,在查阅了一些方案以后,遂决定自己手写代码实现验证码识别,分享一下整个过程。 图片验证码是什么 图片验证码...
  • java识别验证码

    2019-12-10 14:48:27
    之前在做数据核对部分工作,需要获取厂商的...这里记录一下识别验证码的过程。 使用tess4j 1.下载tessdata和训练语言包  在tessract的github直接下载即可,下载地址戳我(只需要项目的 tessdata文件夹 )。这里,...
  • import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.I...
  • 本节我们就以知网的验证码为例,讲解一下利用 OCR 技术识别此种图形验证码的方法。 准备工作 识别图形验证码需要的库有 Tesserocr,如果没有安装可以参考第一章的安装说明。 获取验证码 为了便于实验,我们先将...
  • 爬虫识别图形验证码

    千次阅读 2021-11-18 13:15:09
    import ddddocr ocr = ddddocr.DdddOcr() with open('code.png', 'rb') as f: img_bytes = f.read() res = ocr.classification(img_bytes) print(res)
  • Java+python识别验证码

    2019-07-29 21:39:55
    爬虫要爬取网站,很重要的一步是识别验证码,只有识别验证码之后才可以进行之后的操作。 识别验证码 下载验证码 下载比较好解决,方式很多。这里不多说,先保存多张验证码。 随便打开一张图片,发现背景图有黑点,...
  • 使用tess4j原因是验证码图片地址由js动点击打开链接态生成,和时间戳有关,导致常规爬虫获取图片地址下载的方法得到的验证码与网页显示的不同,所以想到使用截屏方案截取验证码图片,使用tess4j进行识别,达到自动...
  • 对于网络爬虫而言,解决验证码识别识别是非常重要的一件事。 今天,我们将讨论有关验证码的5件事,以帮助大家更好的进行网络数据抓取。 1. 什么是验证码? 2. 验证码是如何工作的? 3. 常见的验证码有哪些类型?...
  • 那周周五的boss突然问我会不会爬虫。 作为一个才工作一年的javaer表示根本没接触过,但是那种情况下你还敢说不会么,但是当时也不敢说的很绝对,因此就和boss就会一点。 当时就隐隐约约有爬虫任务了,感觉周末去突击...
  • pom.xmlcom.github.whvcseeasy-captcha1.6.2生成验证码:public NutMap getCode() {String uuid = UUID.randomUUID().toString().replace("-", "");ArithmeticCaptcha captcha = new ArithmeticCaptcha(120, 40);...
  • Java整合ORC识别验证码

    2016-02-14 12:54:42
    首先需要下载orc软件,这里使用tesseract-orc软件好了 ...下载好了,就安装。 我们可以测试一下,在命令行输入tesseract 会出现以下情况 如果没有出现以下情况,需要手动的配置...ClearImageHelper.javaimport java.
  • Java 验证码识别库 Tess4j学习【在用java的Jsoup做爬虫爬取数据时遇到了验证码识别的问题(基于maven),找了网上挺多的资料,发现Tess4j可以自动识别验证码,在这里简单记录下学习过程及遇到的一些问题。】步骤:需要...
  • 破解验证码有个方法里参数是path,验证码在网上,怎么把它弄下来,path怎么写

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,411
精华内容 964
关键字:

java爬虫识别验证码

java 订阅
爬虫 订阅