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

因为最近有部分小伙伴私信我询问关于我很久前写的一个教务系统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发生改变,那么代码也得随之改变,这也是其缺点之一吧。那么本文就到此啦,如有哪里讲解有误还望体谅~ 谢谢大家~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,566评论 25 707
  • 苏州十公里跑回来之后变得懒惰了不少,简直就想懒死了算了的状态。天天都是晚上不想睡,早上起不来的神经紧绷状态。 说好...
    梁木纯阅读 369评论 1 1
  • 厂里面的叉车司机,虽栽培半载有余,但要说起那车上的功夫却足以令人闻风丧胆,素有‘杀手’的名头,因为无论多么齐整...
    昭昭之辉阅读 254评论 0 1
  • 不管是谁的过错,总之我们已经错过。
    Myheng_a3d7阅读 139评论 0 0