Android开发部落安卓Utils

Android利用Jsoup抓取数据,再也不怕写App没有数据啦

2017-03-27  本文已影响2295人  EoniJJ

因为最近有部分小伙伴私信我询问关于我很久前写的一个教务系统App的一些问题,鉴于那个项目实在是停止维护太久了,代码都是一年多前写的,已经登陆不进去了,本着授人与鱼不如授人与渔的原则,于是写了这篇博客。

原理很简单,阅读本文大概需要3分钟。

Jsoup介绍

先附上官方介绍:

Jsoup is a Java library for working with real-world HTML. It provides a very convenient API for extracting and manipulating data, using the best of DOM, CSS, and jquery-like methods.

Jsoup是一个用来处理html文本的java库。它提供了非常方便的API,可以通过dom,css或者类似jquery的方法来提取和操作数据。

嗯,所以他到底是干嘛的呢? 当我们访问一个网站拿到它的html代码的时候,往往我们所需要的一些数据就已经包含在html里,Jsoup就是帮我们把这些我们想要的数据提取出来。还是不够清晰明了?没关系,我们一起来看一个demo。

Demo

这里我们以简书为例子,抓取简书中我们想要的数据。

众所周知,简书的url为http://www.jianshu.com/ ,我们通过浏览器访问它,并按F12(这里我使用的chrome浏览器)。

简书首页 get请求

这里可以看到简书首页的html代码,我们要实现的就是把首页的文章列表提取出来。

目标明确,可以开始撸代码了。

首先先在build.gradle里添加Jsoup的依赖

dependencies {
        compile 'org.jsoup:jsoup:1.10.2'
}

既然Jsoup是对html进行操作,那么首先我们肯定要拿到html嘛,这里我使用okhttp发起请求,大家也可以根据自己喜好自行替换

        Request request = new Request.Builder().
                url("http://www.jianshu.com").
                //如果请求的url需要提交参数,那么需改为post方式并提交对应的参数
                get().
                build();
        okHttpClient.newCall(request).enqueue(this);
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            String result = response.body().string();
            parseHtml(result);
        }
    }

这里没什么特别的,无非就是发送请求,拿到返回的html。

好现在我们已经成功拿到简书首页的html代码,这里我们先回到浏览器,按住ctrl+shift+c(chrome浏览器下的快捷键) ,点击一下列表的其中一篇文章,



可以看到,li这个标签是包含在id为list-container的div中的ul里面。

点击标题

点击标题,可以看到标题是包含在li里面的class为title的a标签里面的,并且文章的详情页面的url也包含在href属性里面,对jq或者js熟悉的童鞋可能知道,在jq或者js中我们是可以通过标签来寻找元素的,回顾一下Jsoup的简介,可以使用类似jquery的方法提取或者操纵数据,是不是大概明白了。

我们来看一下代码实现

private void parseHtml(String html) {
        //将html转为Document对象
        Document document = Jsoup.parse(html);
        //获得li的元素集合
        Elements elements = document.select("div#list-container ul li");
        List<BlogModel> lists = new ArrayList<>();
        BlogModel blogModel;
        for (Element element : elements) {
            //获得作者
            String author = element.select("div.name a").first().text();
            //获得标题
            String title = element.select("a.title").first().text();
            //获得图片url,因为文章有可能没有图片,所以这里需要特殊处理一下
            String image = element.select("a.wrap-img").first() != null ?
                    element.select("a.wrap-img").first().children().first().attr("src") : "";
            //获得文章详情url
            String targetUrl = element.select("a.title").first().attr("href");
            blogModel = new BlogModel();
            blogModel.setAuthor(author);
            blogModel.setName(title);
            blogModel.setImage(image);
            blogModel.setTargetUrl(targetUrl);
            lists.add(blogModel);
        }
    }

这里我们将拿到的数据都封装成一个BlogModel对象,BlogModel的代码很简单

public class BlogModel {
    private String author;
    private String name;
    private String image;
    private String targetUrl;
    
    //get和set方法...
}

现在我们已经拿到需要的数据了,接下来无非就是展示了。这里我是用RecyclerView,简单贴一下Adapter的代码

    static class MyAdapter extends RecyclerView.Adapter<ViewHolder> {
        private Context context;
        private List<BlogModel> blogModels;

        public MyAdapter(Context context) {
            this.context = context;
        }

        public void setBlogModels(List<BlogModel> blogModels) {
            this.blogModels = blogModels;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new ViewHolder(View.inflate(context, R.layout.item_blog, null));
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            holder.tvTitle.setText(blogModels.get(position).getName());
            Glide.with(context).load(blogModels.get(position).getImage()).into(holder.ivImg);
        }

        @Override
        public int getItemCount() {
            return blogModels.size();
        }
    }

怎么去展示数据大家肯定都很熟悉了,这里就不啰嗦了,最后上一下demo图片

Demo

总结

Ok啦,通过Jsoup可以抓取各种网页的数据,例如你学校的教务网等等,这里我们只是简单介绍了一下Jsoup的基本用法,细心的童鞋肯定发现啦,使用Jsoup抓取数据时如果抓取的网站的html发生改变,那么代码也得随之改变,这也是其缺点之一吧。那么本文就到此啦,如有哪里讲解有误还望体谅~ 谢谢大家~

上一篇下一篇

猜你喜欢

热点阅读