Java爬虫---实战案例(爬取彼岸桌面壁纸)

2 篇文章 0 订阅

平时玩的爬虫都是用python写的,今天突发奇想的用java写了一个,整个分析的过程和使用python是一样的,都是一样的思路,唯一的区别可能就是语言的不同了,也就是命令和语法。废话不多说,直接进入正题,在此之前还是先贴一下效果图吧。


效果图:

在这里插入图片描述


在这里插入图片描述



壁纸下载地址:http://www.netbian.com/fengjing/

工具:IDEA

项目创建:Maven


步骤一:创建项目


这一步就不做过多的讲解了,如果有不太了解的地方,可以参考这篇文章:项目管理工具 Maven 的下载,安装,配置以及项目的创建和管理

这里只把项目中的pom.xml配置文件贴一下:

要注意的是配置文件中的依赖
在这里插入图片描述

步骤二:网页分析


在这个页面我们只能获取到缩略图片,没办法获取到大图,我们随便点开一个进入详情页

在这里插入图片描述

在这个页面我们已经可以获取到大图了
在这里插入图片描述

按"F12"打开检查,查看图片路径
在这里插入图片描述

打开这个url,我们可以看到这就是我们想要下载的图片
在这里插入图片描述


上面就是我们获取到图片的一个流程,那写代码的步骤是什么呢?

1.在缩略图页面获取到详情页的超链接
2.在详情页页面获取到图片的下载地址



1.在缩略图页面获取到详情页的超链接

在这里插入图片描述

如果直接获取a标签那肯定有很多是我们不需要的,所以我们用从外到内的方式进行获取,过滤掉其他不需要的a标签
在这里插入图片描述

代码部分:

将获取到的所有详情页的url存储到一个列表中,方便我们后续使用

//    获取a标签中的href属性值并将其存储到列表中
    public List<String> GetElementUrl(List<String> list){
        for(String url: list){
            try {
//                需要导入Jsoup包
                String html = Jsoup.connect(url).execute().body();
//                解析源代码
                Document document = Jsoup.parse(html);
//                获取元素
                Elements elements = document.select("div[id=main]").select("div[class=list]").select("ul").select("li").select("a");
//                遍历所有元素
                for (int i = 0; i < elements.size(); i++){
//                    获取a标签中href属性的值
                    String aUrl = elements.get(i).attr("href");
//                    里面还是有我们不需要的,所以这里还要设置一个条件来进行过滤
                    if(!aUrl.contains("https:")){
//                        将属性值存储到列表中
                        AUrlList.add(aUrl);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return AUrlList;
    }


2.在详情页页面获取到图片的下载地址

这就是图片的下载地址
在这里插入图片描述

获取这里的img标签和我们上一步获取a标签是一样的,我们还是采用从外到内的方式获取,以达到过滤的目的
在这里插入图片描述

代码部分:

把获取到的img标签中的src属性值存储到列表中,图片名称也存储到列表中

//    获取img标签中的src属性值,并将其存储到列表中
    public List<String> GetImageUrl(List<String> list){
        for (Object o : list) {
//            将url补充完整
            try {
                URL aUrl = new URL("http://www.netbian.com" + (String) o);
                URLConnection conn = aUrl.openConnection();
                InputStream is=conn.getInputStream();
//                获取的源代码乱码,此处解决乱码问题
                BufferedReader br = new BufferedReader(new InputStreamReader(is,"gbk"));
                String html = null;
                String line = null;
                while((line = br.readLine()) != null){
                    html = html + line;
                }
                Document document = Jsoup.parse(html);
//                获取img标签
                Elements elements = document.select("div[id=main]").select("div[class=endpage]").select("div[class=pic]").select("p").select("a").select("img");
//                获取img标签中的src属性值
                String ImageURL = elements.attr("src");
//                获取图片名
                String ImageName = elements.attr("title");
//                将图片src属性值存储到列表中
                ImageUrlList.add(ImageURL);
//                将图片名存入列表中
                ImageNameList.add(ImageName);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ImageUrlList;
    }

解释一个地方

其实,上面的这部分代码(第一部分)

URL aUrl = new URL("http://www.netbian.com" + (String) o);
URLConnection conn = aUrl.openConnection();
InputStream is=conn.getInputStream();
//获取的源代码乱码,此处解决乱码问题
BufferedReader br = new BufferedReader(new InputStreamReader(is,"gbk"));
String html = null;
String line = null;
while((line = br.readLine()) != null){
	html = html + line;
}

等价于这部分代码(第二部分)

String html = Jsoup.connect("http://www.netbian.com" + (String) o).execute().body();

那为什么还要用代码多的那部分呢?

主要是因为这里涉及到乱码的问题,我们获取到的源代码会显示乱码,用第二部分代码获取源代码我还没有找到解决乱码的方法,所以只能用第一部分代码来获取源代码并且解决乱码的问题,如果大家有更简单的方法,可以写在评论区或者私信我,一定虚心请教。

在这里插入图片描述




步骤三:图片下载


单独定义一个用于下载的方法,只需要传入存储img标签src属性值的列表即可

代码部分:

//    下载图片
    public void DownLoadToLocal(List<String> list){
        int len;
        for (int i =0; i < list.size(); i++){
            try {
//                创建url对象
                URL ImgUrl = new URL(list.get(i));
                URLConnection con = ImgUrl.openConnection();
//                创建输入流对象
                InputStream is = con.getInputStream();
                byte[] bs = new byte[1024];
//                图片名
                String ImgName = ImageNameList.get(i);
//                本地存储路径
                String LocalUrl = SaveUrl + ImgName + ".jpg";
//                创建文件对象
                File file = new File(LocalUrl);
//                创建输出流对象,当文件不存在时会自动创建,true表示追加写入
                FileOutputStream os = new FileOutputStream(file,true);
//                read()从输入流中读取下一个字节。如果没有字节可读(文件读取完成)返回-1
                while ((len = is.read(bs)) != -1){
//                从字节数组bs中,将偏移量从0开始的len个字节写入此文件输出流
                    os.write(bs,0,len);
                }
                System.out.println("图片  " + ImgName + "  下载成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

翻页功能


这里我还定义了一个翻页的方法,原理很简单也很直观,因为每页的url我们可以直接看到,所以我们只需要按照规律使用字符串拼接拼凑出每页的url即可

第一页
在这里插入图片描述

第二页
在这里插入图片描述

第三页
在这里插入图片描述

一眼就看出规律了吧,所以只要按照这个规律去拼凑每页的url就可以了,从而实现翻页功能。

代码部分:

要注意的是第一页的url有点特殊,别忘了单独处理

//    指定下载页数
    public void DownLoadPage(int AllPage){
        String PageUrl;
        List<String> EleList = null;
        for(int i = 1; i <= AllPage; i++){
            if(i == 1){
//                将第一页的url添加到列表中
                BaseUrlList.add(baseurl);
            }else {
//                其他页的url
                PageUrl = baseurl + "index_" + i + ".htm";
//                将其他页的url添加到列表中
                BaseUrlList.add(PageUrl);
            }
        }
    }


下面是源代码,感觉这篇文章有意思的话,还请多多支持呀,你们的支持是我创作的最大动力。

在这里插入图片描述



源代码

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

public class GetBackground {
//    下载图片类别入口,输入所要下载类别的第一页的url
    static String baseurl = "http://www.netbian.com/fengjing/";
//    本地存储路径
    static String SaveUrl = "D:/图片/";
//    存储不同下载页面的url
    static List<String> BaseUrlList = new ArrayList<String>();
//    存储a标签中的url
    static List<String> AUrlList = new ArrayList<String>();
//    存储img标签中的url
    static List<String> ImageUrlList = new ArrayList<String>();
//    存储图片名称
    static List<String> ImageNameList = new ArrayList<String>();

//    程序入口
    public static void main(String[] args) {
        GetBackground getBackground = new GetBackground();
//        System.out.println(EleList);
        getBackground.DownLoadPage(2);
        List<String> EleList = getBackground.GetElementUrl(BaseUrlList);
        List<String> ImgList = getBackground.GetImageUrl(EleList);
        getBackground.DownLoadToLocal(ImgList);
    }

//    获取a标签中的href属性值并将其存储到列表中
    public List<String> GetElementUrl(List<String> list){
        for(String url: list){
            try {
//                需要导入Jsoup包
                String html = Jsoup.connect(url).execute().body();
//                解析源代码
                Document document = Jsoup.parse(html);
//                获取元素
                Elements elements = document.select("div[id=main]").select("div[class=list]").select("ul").select("li").select("a");
//                遍历所有元素
                for (int i = 0; i < elements.size(); i++){
//                    获取a标签中href属性的值
                    String aUrl = elements.get(i).attr("href");
//                    里面还是有我们不需要的,所以这里还要设置一个条件来进行过滤
                    if(!aUrl.contains("https:")){
//                        将属性值存储到列表中
                        AUrlList.add(aUrl);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return AUrlList;
    }

//    获取img标签中的src属性值,并将其存储到列表中
    public List<String> GetImageUrl(List<String> list){
        for (Object o : list) {
//            将url补充完整
            try {
                URL aUrl = new URL("http://www.netbian.com" + (String) o);
                URLConnection conn = aUrl.openConnection();
                InputStream is=conn.getInputStream();
//                获取的源代码乱码,此处解决乱码问题
                BufferedReader br = new BufferedReader(new InputStreamReader(is,"gbk"));
                String html = null;
                String line = null;
                while((line = br.readLine()) != null){
                    html = html + line;
                }
                Document document = Jsoup.parse(html);
//                获取img标签
                Elements elements = document.select("div[id=main]").select("div[class=endpage]").select("div[class=pic]").select("p").select("a").select("img");
//                获取img标签中的src属性值
                String ImageURL = elements.attr("src");
//                获取图片名
                String ImageName = elements.attr("title");
//                将图片src属性值存储到列表中
                ImageUrlList.add(ImageURL);
//                将图片名存入列表中
                ImageNameList.add(ImageName);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ImageUrlList;
    }

//    下载图片
    public void DownLoadToLocal(List<String> list){
        int len;
        for (int i =0; i < list.size(); i++){
            try {
//                创建url对象
                URL ImgUrl = new URL(list.get(i));
                URLConnection con = ImgUrl.openConnection();
//                创建输入流对象
                InputStream is = con.getInputStream();
                byte[] bs = new byte[1024];
//                图片名
                String ImgName = ImageNameList.get(i);
//                本地存储路径
                String LocalUrl = SaveUrl + ImgName + ".jpg";
//                创建文件对象
                File file = new File(LocalUrl);
//                创建输出流对象,当文件不存在时会自动创建,true表示追加写入
                FileOutputStream os = new FileOutputStream(file,true);
//                read()从输入流中读取下一个字节。如果没有字节可读(文件读取完成)返回-1
                while ((len = is.read(bs)) != -1){
//                从字节数组bs中,将偏移量从0开始的len个字节写入此文件输出流
                    os.write(bs,0,len);
                }
                System.out.println("图片  " + ImgName + "  下载成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

//    指定下载页数
    public void DownLoadPage(int AllPage){
        String PageUrl;
        List<String> EleList = null;
        for(int i = 1; i <= AllPage; i++){
            if(i == 1){
//                将第一页的url添加到列表中
                BaseUrlList.add(baseurl);
            }else {
//                其他页的url
                PageUrl = baseurl + "index_" + i + ".htm";
//                将其他页的url添加到列表中
                BaseUrlList.add(PageUrl);
            }
        }
    }

}




关注公众号,获取相关资料和更多有趣文章(有什么问题可以私信我)
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值