真香警告!教你用java爬虫下载网站的图片,

前言:前几天刚跑完2020男子半程马拉松,对于我一个跑渣来说能够跑完全程已经是善莫大焉了,跑完我累的不要不要的,不是这里痛就是那里痛,还是练少了,平常训练量不够,勉勉强强就上了。

跑的时候不知不觉被偷拍了,后来了解到这个是有专门的人去拍的,会根据你的号码牌识别到你这个人,群里有人说在一个微信公众号里可以查,于是我迫不及待的去搜下我的照片,结果

 

既然是图片,总归有个后台访问的路径吧,于是我用电脑端的微信打开公众号,左上角的有个复制链接,然后再用谷歌浏览器打开,打开调试模式。

 

发现真的个后台地址,我尝试着打开链接,然后图片另存为,还真的拿到原图了,但是,一张的复制感觉太慢了,作为一个不入流的程序员的我来说,百度能解决一切问题,搜到了一个篇博客,在基础上稍微做下修改下。

我试着用java自带的 URLConnection 类去连接该网址,发现该网站是有做反爬虫处理的,爬取到是一些js文件,而不是包含图片的那个源码,于是我换个思路,不用网址去爬,直接从谷歌浏览器控制台复制html文本到本地文件,然后利用java的文件流读取,进行解析,过滤,然后再输出到本地。原理就是java流读取,流输出。接下来看我一是如何一步一步实现的。

一.复制html文本到本地

 

二.利用java 字节流读取,利用正则过滤<img>标签和src路径

利用流读取文件 的方法

public String getFileImage(String path) throws Exception {
        File file = new File(path);

        InputStream inputStream = new FileInputStream(file);
        InputStreamReader isr = new InputStreamReader(inputStream);//流的包装
        BufferedReader br = new BufferedReader(isr);

        String line;
        StringBuffer sb = new StringBuffer();
        while ((line = br.readLine()) != null) {//整行读取
            sb.append(line, 0, line.length());//添加到StringBuffer中
            sb.append('\n');//添加换行符
        }
        //关闭各种流,先声明的后关闭
        br.close();
        isr.close();

        return sb.toString();
    }

 正则表达式过滤<img>标签的方法

public List getImg(String html) {
        List list = new ArrayList();
        String regex = "<img.*?>";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(html);
        while (matcher.find()) {
            list.add(matcher.group());
        }
        return list;
    }

正则表达式获取img标签src属性值

 //获取ImageSrc地址
    private List<String> getImageSrc(List<String> listimageurl) {
        List<String> listImageSrc = new ArrayList<String>();
        for (String image : listimageurl) {
            Matcher matcher = Pattern.compile(IMGSRC_REG).matcher(image);
            while (matcher.find()) {
                listImageSrc.add(matcher.group().substring(0, matcher.group().length() - 1));
            }
        }
        return listImageSrc;
    }

测试

String fileImage = getFileImage("C:\\Users\\Desktop\\imagefile.txt");
        List img = getImg(fileImage);
        List<String> imageSrc = getImageSrc(img);
        System.out.println(imageSrc);

结果是个存放src地址的集合

到这一步就已经接近成功了

三.输出流,执行下载

方法

 //下载图片
    private void download(List<String> listImgSrc) {
        try {
            String path="D:\\malasongImage";
            //开始时间
            Date begindate = new Date();
            for (String url : listImgSrc) {
                //开始时间
                Date begindate2 = new Date();
                String imageName = url.substring(url.lastIndexOf("/") + 1, url.length());
                URL uri = new URL(url);
                InputStream in = uri.openStream();
                File outFiledir=new File(path);
                SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy/MM/dd");
                String date = dateFormat.format(new Date());
                int out=1;
                File image=new File(outFiledir.getAbsolutePath()+File.separator+imageName);
                if (!outFiledir.exists()){
                    outFiledir.mkdir();
                }
                System.out.println(outFiledir.getAbsolutePath());
                System.out.println("具体路径:"+image.getName());
                FileOutputStream fo = new FileOutputStream(image);//文件输出流
                byte[] buf = new byte[1024];
                int length = 0;
                System.out.println("开始下载:" + url);
                while ((length = in.read(buf, 0, buf.length)) != -1) {
                    fo.write(buf, 0, length);
                }
                //关闭流
                in.close();
                fo.close();
                System.out.println(imageName + "下载完成");
                //结束时间
                Date overdate2 = new Date();
                double time = overdate2.getTime() - begindate2.getTime();
                System.out.println("耗时:" + time / 1000 + "s");
            }
            Date overdate = new Date();
            double time = overdate.getTime() - begindate.getTime();
            System.out.println("总耗时:" + time / 1000 + "s");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("下载失败");
        }
    }

执行结果

String fileImage = getFileImage("C:\\Users\\Desktop\\imagefile.txt");
        List img = getImg(fileImage);
        List<String> imageSrc = getImageSrc(img);
        System.out.println(imageSrc);
        download(imageSrc);

大功告成,真香警告!

 

 补充: 以上是针对反爬虫的网站,下面提供的方法可以爬取没有做反爬虫的网站上截取图片。

// 获取img标签正则
    private static final String IMGURL_REG = "<img.*?>";
    // 获取src路径的正则
    private static final String IMGSRC_REG = "[a-zA-z]+://[^\\s]*";
//获取HTML内容
    private String getHtml(String url) throws Exception {
        URL url1 = new URL(url);//使用java.net.URL
        URLConnection connection = url1.openConnection();//打开链接
        InputStream in = connection.getInputStream();//获取输入流
        InputStreamReader isr = new InputStreamReader(in);//流的包装
        BufferedReader br = new BufferedReader(isr);

        String line;
        StringBuffer sb = new StringBuffer();
        while ((line = br.readLine()) != null) {//整行读取
            sb.append(line, 0, line.length());//添加到StringBuffer中
            sb.append('\n');//添加换行符
        }
        //关闭各种流,先声明的后关闭
        br.close();
        isr.close();
        in.close();
        return sb.toString();
    }
//获取ImageUrl地址
    private List<String> getImageUrl(String html) {
        Matcher matcher = Pattern.compile(IMGURL_REG).matcher(html);
        List<String> listimgurl = new ArrayList<String>();
        while (matcher.find()) {
            listimgurl.add(matcher.group());
        }
        return listimgurl;
    }
//获取ImageSrc地址
    private List<String> getImageSrc(List<String> listimageurl) {
        List<String> listImageSrc = new ArrayList<String>();
        for (String image : listimageurl) {
            Matcher matcher = Pattern.compile(IMGSRC_REG).matcher(image);
            while (matcher.find()) {
                listImageSrc.add(matcher.group().substring(0, matcher.group().length() - 1));
            }
        }
        return listImageSrc;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

study@lin017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值