欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

简单的图片采集器(网络爬虫原理)

程序员文章站 2024-02-10 16:04:28
...

1.学习目的:熟悉java类集以及IO流操作,为图片识别做采集铺垫
2.对象网站http://www.ivsky.com
3.制作思路: 1. 输入一个网址,获取该网址的html内容.
2. 分析html内容,提取到所有网址和图片地址
3. 如果是遍历网址就循环对每个网址重复做步骤一和步骤2,如果是图片,就下载图片。(所有方法都做函数封装)

没做界面,就一个简单的控制台程序(输入数字即可运行),效果图如下:
简单的图片采集器(网络爬虫原理)

源代码和源文件(在最下面)如下:

1.SpiderHelp.java文件(封装各个函数)

package spider;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SpiderHelp {
    static int cou=0;//记图片的数量
    /**
     * 下载功能
     * 
     * @param urlString
     * @param filename
     * @param savePath
     * @throws Exception
     */
    public static void download(String urlString, String filename, String savePath) {

        try {
            // 构造URL
            URL url = new URL(urlString);
            // 打开连接
            URLConnection con = url.openConnection();
            // 设置请求超时为5s
            con.setConnectTimeout(5 * 1000);
            // 输入流
            InputStream is = con.getInputStream();

            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流
            File sf = new File(savePath);
            if (!sf.exists()) {
                sf.mkdirs();
            }
            OutputStream os = new FileOutputStream(sf.getPath() + "\\" + filename);
            // 开始读取
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
            }

        } catch (Exception e) {
            // TODO: handle exception
        } finally {

        }
    }

    /**
     * 传入一个网址字符串返回网页的html内容
     * 
     * @param webSite
     * @return String
     * @throws Exception
     */
    public static String getWebConcent(String webSite) {
        try {
            // 定义即将访问的链接
            String url = webSite;
            // 定义一个字符串用来存储网页内容
            String result = "";
            // 定义一个缓冲字符输入流
            BufferedReader in = null;
            // 将url的string字符串转成url对象
            URL realUrl = new URL(url);
            // 初始化一个连接到那个URL链接
            URLConnection connection = realUrl.openConnection();
            // 开始实际连接
            connection.connect();
            // 初始化BufferedReader输入流来读取URL的响应并指定字符串编码为UTF-8
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            // 用来临时存储抓取到每一行的数据
            String line;
            while ((line = in.readLine()) != null) {
                // 遍历抓取到的每一行并将其存储到result里面
                result += line;
            }
            // TODO: handle exception
            in.close();
            // System.out.println(result);
            return result;
        } catch (Exception e) {
            // TODO: handle exception
        }
        return "";
    }

    /**
     * 输入字符串和正则匹配字符,返回分割的字符
     * 
     * @param regex
     * @param str
     * @return String
     */
    public static String splitStringOne(String regex, String str) {

        try {
            Pattern pattern = Pattern.compile(regex); // 定义一个模版
            Matcher matcher = pattern.matcher(str);// 定义一个匹配类
            String str1 = new String();
            if (matcher.find()) { // 开始搜索匹配的字符串
                str1 = matcher.group(0);// 将匹配的字符串赋给str1
            } else {
                str1 = "";
            }
            return str1;// 返回字符串
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "";// 返回字符串
    }

    /**
     * 输入字符串和正则匹配字符,返回分割字符是否成功
     * 
     * @param regex
     * @param str
     * @return String
     */
    public static boolean splitStringOneWithJudge(String regex, StringBuffer strBuf) {
        Pattern pattern = Pattern.compile(regex); // 定义一个模版
        Matcher matcher = pattern.matcher(strBuf);
        // String str1 = new String();

        if (matcher.find()) {
            String str1 = matcher.group(0);
            int strBufLength = strBuf.length();
            strBuf.replace(0, strBufLength, "");
            strBuf.append(str1);
            return true;
        }

        return false;
    }

    /**
     * 传入一个网址字符串返回分割好的字符串数组
     * 
     * @param webSite
     * @return String
     * @throws Exception
     */
    public static String[] splitStringMany(String regex, String str) {
        if (!("".equals(str))) {
            Pattern pattern = Pattern.compile(regex); // 定义一个模版
            Matcher matcher = pattern.matcher(str);
            String[] str1 = new String[0];
            // str1=str.split(regex, 20);

            while (matcher.find()) {
                String[] cloned = new String[str1.length + 1];
                System.arraycopy(str1, 0, cloned, 0, cloned.length - 1);
                cloned[cloned.length - 1] = matcher.group();
                str1 = cloned;
            }
            // for ( String string2 : str1 )
            // {
            // System.out.println (string2);
            // }
            return str1;
        } else {
            return null;
        }
    }

    /**
     * 截取字符串数组中的字符,并返回字符串数组
     * 
     * @param regex
     * @param str
     * @return 字符串数组
     */
    public static String[] splitStringMany(String regex, String str[]) {
        // 遍历str[]数组中的每一个元素,根据正则表达式分割
        for (int i = 0; i < str.length; i++) {
            str[i] = splitStringOne(regex, str[i]);
        }
        return str;
    }

    /**
     * 对图片天堂网一个进行下载图片网址
     * 
     * @throws Exception
     * 
     */
    public static void imgDownloadToHeavenWeb(String url) {
        try {

            String regex = "<img.*?>";// 定义获取img标签的正则表达式
            String[] str1 = null;// 定义接收img标签的数组
            SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
            // String str =
            // spiHel.getWebConcent("http://www.ivsky.com/tupian/ziranfengguang/");//
            // 获取该网站的数据
            String str = spiHel.getWebConcent(url);
            System.out.println("原始数据为" + str);// 输出原始数据
            System.out.println("==================");
            str1 = spiHel.splitStringMany(regex, str); // 对数据进行分割并将数据保存在数组里面
            for (int i = 0; i < str1.length; i++) { // 输出第一次提取的数据
                System.out.println("第" + i + "条数据为" + str1[i]);
            }
            System.out.println("==================");
            str1 = spiHel.splitStringMany("src=\".*?\"", str1);// 在对数据进行第二次提取
            for (int i = 0; i < str1.length; i++) {
                System.out.println("第" + i + "条数据为" + str1[i]);
            }
            System.out.println("==================");
            str1 = spiHel.splitStringMany("http.+jpg", str1);// 在对数据进行第二次提取
            for (int i = 0; i < str1.length; i++) {
                System.out.println("第" + i + "条数据为" + str1[i]);
            }
            System.out.println("==================");
            // 下载图片测试
            for (int i = 0; i < str1.length; i++) {
                String s = getPresentTime() + "第" + cou++ + "张图片.jpg"; // 定义每一张图片名字并设置后缀名

                if (!("".equals(str1[i]))) {
                    System.out.println("第" + cou + "张图片正在下载");
                    spiHel.download(str1[i], s, "d:\\image\\");// 遍历网址并下载图片

                }

                System.out.println("==================");
            }
        } catch (Exception e) {
            // TODO: handle exception
        }

    }

    /**
     * 对图片天堂网的网址进行分割,如果与原网址相等则返回空
     * 
     * @return
     */
    public static String[] htmlDivisionToHeavenWeb(String url) throws Exception {
        SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
        String[] str1 = null;// 定义接收img标签的数组
        String str = spiHel.getWebConcent(url);
        // 测试对网址的提取
        str1 = spiHel.splitStringMany("<a.*?>", str); // 对数据进行第一次分割并将数据保存在数组里面
        if (str1 != null) {
            for (int i = 0; i < str1.length; i++) {
                System.out.println("第" + i + "条数据为" + str1[i]);
            }
            System.out.println("==================");
            str1 = spiHel.splitStringMany("href=[\'\"].*?[\'\"]", str); // 对数据进行第二次分割并将数据保存在数组里面
            for (int i = 0; i < str1.length; i++) {
                System.out.println("第" + i + "条数据为" + str1[i]);
            }

            System.out.println("==================");
            str1 = spiHel.splitStringMany("/.*/", str1); // 对数据进行第三次分割并将数据保存在数组里面
            for (int i = 0; i < str1.length; i++) {
                if ("".equals(str1[i])) {
                    str1[i] = "";

                } else if ("/".equals(str1[i])) {
                    str1[i] = "";
                } else if ("//".equals(str1[i])) {
                    str1[i] = "";
                } else {
                    str1[i] = "http://www.ivsky.com" + str1[i];
                    System.out.println("第" + i + "条数据为" + str1[i]);
                }
            }
            return str1;
        } else
            return null;
    }

    /**
     * 对图片天堂网的网址进行分割,如果与原网址相等则返回空,只返回网址
     * 
     * @return
     */
    public static String[] htmlDivisionToHeavenOnly(String url) throws Exception {
        if("".equals(url)){
            return null;
        }
        else{
            SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
            String[] str1 = null;// 定义接收img标签的数组
            String str = spiHel.getWebConcent(url);
            // 测试对网址的提取
            str1 = spiHel.splitStringMany("<a.*?>", str); // 对数据进行第一次分割并将数据保存在数组里面
            if (str1 != null) {
                // for (int i = 0; i < str1.length; i++) {
                // System.out.println("第" + i + "条数据为" + str1[i]);
                // }
                // System.out.println("==================");
                str1 = spiHel.splitStringMany("href=[\'\"].*?[\'\"]", str); // 对数据进行第二次分割并将数据保存在数组里面
                // for (int i = 0; i < str1.length; i++) {
                // System.out.println("第" + i + "条数据为" + str1[i]);
                // }

                // System.out.println("==================");
                str1 = spiHel.splitStringMany("/.*/", str1); // 对数据进行第三次分割并将数据保存在数组里面
                for (int i = 0; i < str1.length; i++) {
                    if ("".equals(str1[i])) {
                        str1[i] = "";

                    } else if ("/".equals(str1[i])) {
                        str1[i] = "";
                    } else if ("//".equals(str1[i])) {
                        str1[i] = "";
                    } else if ("/img/".equals(str1[i])) {
                        str1[i] = "";
                    } else {
                        str1[i] = "http://www.ivsky.com" + str1[i];
                        System.out.println("第" + i + "条数据为" + str1[i]);
                    }
                }
                return str1;
            } else
                return null;
        }

    }

    /**
     * 获取当前系统时间并返回自定义格式
     * 
     * @return
     */
    public static String getPresentTime() {
        Calendar calendar = new GregorianCalendar();
        StringBuffer strBuf = new StringBuffer();
        strBuf.append(calendar.get(Calendar.YEAR) + "年");
        strBuf.append(calendar.get(Calendar.MONTH) + "月");
        strBuf.append(calendar.get(Calendar.DAY_OF_MONTH) + "日");
        strBuf.append(calendar.get(Calendar.HOUR_OF_DAY) + "时");
        strBuf.append(calendar.get(Calendar.MINUTE) + "分");
        strBuf.append(calendar.get(Calendar.SECOND) + "秒");
        strBuf.append(calendar.get(Calendar.MILLISECOND) + "毫秒");

        String str = strBuf.toString();// 将时间转化为字符串
        return str;

    }

    /**
     * 对全景网一个进行下载图片网址
     * 
     * @throws Exception
     * 
     */
    public static void imgDownloadToanoramaWeb(String url, int number) {
        try {

            SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类
            // 获取该网站的数据

            // 下载图片测试
            for (int i = 0; i < number; i++) {
                String s = getPresentTime() + "第" + i + "张验证码.gif"; // 定义每一张图片名字并设置后缀名

                System.out.println("第" + i + "张验证码正在下载");
                spiHel.download(url, s, "d:\\image\\VerificationCode\\");// 遍历网址并下载图片

                System.out.println("==================");
            }
        } catch (Exception e) {
            // TODO: handle exception
        }

    }
}

2.主函数(程序运行入口)Main.java

package spider;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.SpinnerListModel;
import com.spider.web.model.*;

public class Main {
    public static void main(String[] args) throws Exception {
        SpiderHelp spiHel = new SpiderHelp();// 实例化SpiderHelp类

        // spiHel.imgDownloadToHeavenWeb("http://www.ivsky.com/tupian/banshanbandao_v24024/");

        // SpiderWeb spiWeb=new SpiderWeb();
        // WebNode node=new WebNode("http://www.ivsky.com/");
        // spiWeb.buildSpiderWebTwoLayer(node);
        // 遍历测试
        int n ;
        System.out.println("0.输入0表示遍历天堂图片网");
        System.out.println("1.输入1表示下载图片到D盘下image文件夹");
        System.out.println("2.输入2表示下载验证码到D盘image文件夹下的子文件夹");
        System.out.println("请输入0或者1或者2");
        Scanner scan =new Scanner(System.in);
        n=scan.nextInt();

        switch (n) {
        case 0: { // 遍历网站
            int count = 0;
            System.out.println(
                    "==========================================第一次遍历的网站=============================================");
            String str[] = spiHel.htmlDivisionToHeavenOnly("http://www.ivsky.com/");// 开始下载该网址的图片
            String str1[] = null;
            System.out.println(
                    "==========================================第二次遍历的网站=============================================");
            for (int i = 0; i < str.length; i++) {
                System.out.println("==========================================第二层第" + i
                        + "次遍历的网站=============================================");
                str1 = spiHel.htmlDivisionToHeavenOnly(str[i]);
                if (str1 != null && str1.length != 0) {
                    for (int j = 0; j < str1.length; j++) {
                        System.out.println("==========================================第三层第" + count++
                                + "次读取网址=============================================");
                        if (!("".equals(str1[j]))) {
                            spiHel.htmlDivisionToHeavenOnly(str1[j]);
                        }

                    }
                }

            }
        }
            ;

        case 1: { // 下载图片
            String str2[] = spiHel.htmlDivisionToHeavenWeb("http://www.ivsky.com/tupian/chengshilvyou/");// 开始下载该网址的图片
            if (str2 != null) { // 循环下载图片
                for (int i = 0; i < str2.length; i++) {
                    if (!("".equals(str2[i]))) {
                        spiHel.imgDownloadToHeavenWeb(str2[i]);
                    }
                }
            }
        }
            break;
        case 2: { // 下载验证码
            spiHel.imgDownloadToanoramaWeb("http://www.quanjing.com/createImg.aspx", 200);// 下载验证码
        }
            break;
        case 3: {

        }
            break;
        default:
            break;
        }

    }
}

3.爬虫遍历算法没写完,后面再上传
4.源代码下载地址如下
Spider.rar链接:http://pan.baidu.com/s/1kVge1KF 密码:syua
Spider.exe链接(运行即可看到效果):
链接:http://pan.baidu.com/s/1pLHjVWf 密码:amxu