Android应用开发-小巫CSDN博客clientJsoup篇
距上一篇博客已经过去了两个星期,小巫也认为很抱歉,由于在忙着做另外一个项目,差点儿抽不出空来,这不小巫会把剩下的博文全部在国庆补上。本篇博客将会给大家介绍怎样使用Jsoup这个库来解析我们的网页,而且怎样对我们想解析的网页进行分析。
Jsoup这个库的下载地址:http://jsoup.org/download
笔者这里使用的jsoup-1.7.2
下载完之后拷贝到项目中的libs文件夹下就可以:
Jsoup的资料比較少,可供參考的可到其官网进行学习这个库的使用:http://www.open-open.com/jsoup/
API查阅地址:http://jsoup.org/apidocs/
对这个库的使用笔者也不是很熟悉,就仅仅是简单參考了文档而完毕了解析工作,所下面面的笔者的解析代码也仅仅是提供參考,具体的解析方法,请认真查看api文档。
怎样使用Jsoup这个库不是重点,重点是怎样对我们想解析的网页进行分析,怎样做到像下面的效果:
这里能够看到首页是获取笔者博客的博文列表,每一个条目都有相应的标题、博文摘要、公布时间、阅读数、评论数。这些内容就是通过解析首页html页面所得到的内容。
好,就是这种一个html页面,大伙是不是很想把它搬到手机上呢,仅仅要你学会了怎样分析html页面,你能够把不论什么你想要的内容搬下来,仅仅要你抓取的网页没有做防扒取的措施。
笔者使用的浏览器是Google Chrome,作为专业的IT人士,不用Chrome确实说只是去,按下F12,你就能够看到下面景象,感觉好兴奋啊,能够去寻找你想要的宝藏了。是啊,逗比能够往下看了:
假设想解析一个网页,还是得你自己以上面这种方式去看,找到你想要的内容。小巫是这样做的,能够通过右键查看元素,直接查看相应的html源代码,这样你就知道内容相应的标签是什么了。由于小巫想获得首页的全部博文列表,所以我就找到博文的最外层的div标签開始分析,我找到了id为article_list,然后接着找到了每条博文项的内容,确定下它们的具体的标签,使用了什么class,博客能够通过class来获取你想要的元素,然后取得元素的内容。
直接上代码吧:
/**
* 使用Jsoup解析html文档
*
* @param blogType
* @param str
* @return
*/
public static List<BlogItem> getBlogItemList(int blogType, String str) {
// Log.e("URL---->", str);
List<BlogItem> list = new ArrayList<BlogItem>();
// 获取文档对象
Document doc = Jsoup.parse(str);
// Log.e("doc--->", doc.toString());
// 获取class="article_item"的全部元素
Elements blogList = doc.getElementsByClass("article_item");
// Log.e("elements--->", blogList.toString()); for (Element blogItem : blogList) {
BlogItem item = new BlogItem();
String title = blogItem.select("h1").text(); // 得到标题
// System.out.println("title----->" + title);
String description = blogItem.select("div.article_description")
.text();
// System.out.println("descrition--->" + description);
String msg = blogItem.select("div.article_manage").text();
// System.out.println("msg--->" + msg);
String date = blogItem.getElementsByClass("article_manage").get(0)
.text();
// System.out.println("date--->" + date);
String link = BLOG_URL
+ blogItem.select("h1").select("a").attr("href");
// System.out.println("link--->" + link);
item.setTitle(title);
item.setMsg(msg);
item.setContent(description);
item.setDate(date);
item.setLink(link);
item.setType(blogType); // 没有图片
item.setImgLink(null);
list.add(item); }
return list;
}
小巫通过class="article_item"获取到全部的元素,也就是Element,然后遍历全部的元素,把每一个元素我们须要的值取出来。我们能够定义一个实体类,比方文章项BlogItem,通过创建不同的BlogItem对象,然后最后加入�到list其中,我们就能够把全部博文列表保存下拉,下次取的时候,直接通过list来取就可以。
我们能够看到使用Jsoup这个库,仅仅须要那么少的代码就能够轻松获取到我们想要的内容,编码、效率啥都有,还等什么,去用吧。
然后获取博文具体内容也是相似的,给定一个url,我们就能够相同的方式去解析html代码:
/**
* 扒取传入url地址的博客具体内容
*
* @param url
* @param str
* @return
*/
public static List<Blog> getContent(String url, String str) {
List<Blog> list = new ArrayList<Blog>(); // 获取文档内容
Document doc = Jsoup.parse(str); // 获取class="details"的元素
Element detail = doc.getElementsByClass("details").get(0);
detail.select("script").remove(); // 删除每一个匹配元素的DOM。 // 获取标题
Element title = detail.getElementsByClass("article_title").get(0);
Blog blogTitle = new Blog();
blogTitle.setState(Constants.DEF_BLOG_ITEM_TYPE.TITLE); // 设置状态
blogTitle.setContent(ToDBC(title.text())); // 设置标题内容 // 获取文章内容
Element content = detail.select("div.article_content").get(0); // 获取全部标签为<a的元素
Elements as = detail.getElementsByTag("a");
for (int b = 0; b < as.size(); b++) {
Element blockquote = as.get(b);
// 改变这个元素的标记。比如,<span>转换为<div> 如el.tagName("div");。
blockquote.tagName("bold"); // 转为粗体
} Elements ss = detail.getElementsByTag("strong");
for (int b = 0; b < ss.size(); b++) {
Element blockquote = ss.get(b);
blockquote.tagName("bold");
} // 获取全部标签为<p的元素
Elements ps = detail.getElementsByTag("p");
for (int b = 0; b < ps.size(); b++) {
Element blockquote = ps.get(b);
blockquote.tagName("body");
} // 获取全部引用元素
Elements blockquotes = detail.getElementsByTag("blockquote");
for (int b = 0; b < blockquotes.size(); b++) {
Element blockquote = blockquotes.get(b);
blockquote.tagName("body");
} // 获取全部标签为<ul的元素
Elements uls = detail.getElementsByTag("ul");
for (int b = 0; b < uls.size(); b++) {
Element blockquote = uls.get(b);
blockquote.tagName("body");
} // 找出粗体
Elements bs = detail.getElementsByTag("b");
for (int b = 0; b < bs.size(); b++) {
Element bold = bs.get(b);
bold.tagName("bold");
} // 遍历博客内容中的全部元素
for (int j = 0; j < content.children().size(); j++) {
Element c = content.child(j); // 获取每一个元素 // 抽取出图片
if (c.select("img").size() > 0) {
Elements imgs = c.getElementsByTag("img");
System.out.println("img");
for (Element img : imgs) {
if (!img.attr("src").equals("")) {
Blog blogImgs = new Blog();
// 大图链接
if (!img.parent().attr("href").equals("")) {
blogImgs.setImgLink(img.parent().attr("href"));
System.out.println("href="
+ img.parent().attr("href"));
if (img.parent().parent().tagName().equals("p")) {
// img.parent().parent().remove();
}
img.parent().remove();
}
blogImgs.setContent(img.attr("src"));
blogImgs.setImgLink(img.attr("src"));
System.out.println(blogImgs.getContent());
blogImgs.setState(Constants.DEF_BLOG_ITEM_TYPE.IMG);
list.add(blogImgs);
}
}
}
c.select("img").remove(); // 获取博客内容
Blog blogContent = new Blog();
blogContent.setState(Constants.DEF_BLOG_ITEM_TYPE.CONTENT); if (c.text().equals("")) {
continue;
} else if (c.children().size() == 1) {
if (c.child(0).tagName().equals("bold")
|| c.child(0).tagName().equals("span")) {
if (c.ownText().equals("")) {
// 小标题,咖啡色
blogContent
.setState(Constants.DEF_BLOG_ITEM_TYPE.BOLD_TITLE);
}
}
} // 代码
if (c.select("pre").attr("name").equals("code")) {
blogContent.setState(Constants.DEF_BLOG_ITEM_TYPE.CODE);
blogContent.setContent(ToDBC(c.outerHtml()));
} else {
blogContent.setContent(ToDBC(c.outerHtml()));
}
list.add(blogContent);
} return list;
}
获取评论列表:
/**
* 获取博文评论列表
*
* @param str
* json字符串
* @return
*/
public static List<Comment> getBlogCommentList(String str, int pageIndex,
int pageSize) {
List<Comment> list = new ArrayList<Comment>();
try {
// 创建一个json对象
JSONObject jsonObject = new JSONObject(str);
JSONArray jsonArray = jsonObject.getJSONArray("list"); // 获取json数组
int index = 0;
int len = jsonArray.length();
BlogCommentActivity.commentCount = String.valueOf(len); // 评论条数
// 假设评论数大于20
if (len > 20) {
index = (pageIndex * pageSize) - 20;
} if (len < pageSize && pageIndex > 1) {
return list;
} if ((pageIndex * pageSize) < len) {
len = pageIndex * pageSize;
} for (int i = index; i < len; i++) {
JSONObject item = jsonArray.getJSONObject(i);
String commentId = item.getString("CommentId");
String content = item.getString("Content");
String username = item.getString("UserName");
String parentId = item.getString("ParentId");
String postTime = item.getString("PostTime");
String userface = item.getString("Userface"); Comment comment = new Comment();
comment.setCommentId(commentId);
comment.setContent(content);
comment.setUsername(username);
comment.setParentId(parentId);
comment.setPostTime(postTime);
comment.setUserface(userface); if (parentId.equals("0")) {
// 假设parentId为0的话,表示它是评论的topic
comment.setType(Constants.DEF_COMMENT_TYPE.PARENT);
} else {
comment.setType(Constants.DEF_COMMENT_TYPE.CHILD);
}
list.add(comment);
} } catch (JSONException e) {
e.printStackTrace();
}
return list;
}
具体使用细节能够參考笔者提供的源代码:http://download.csdn.net/detail/wwj_748/7912513
小巫已经把解析html的思路告诉大家啦,剩下怎样来学习jsoup这个库解析html就靠你们自己去做了。下一篇博客预告,集成友盟社会化组件,具体给大家介绍怎样集成友盟提供的社会化组件SDK。

Android应用开发-小巫CSDN博客clientJsoup篇的更多相关文章

  1. Android应用开发-小巫CSDN博客client之嵌入有米广告

    Android应用开发-小巫CSDN博客client之嵌入有米广告 上一篇博客给大家介绍怎样集成友盟社会化组件,本篇继续带来干货,教大家怎样嵌入广告到应用中去.小巫自称专业对接30年,熟悉各大渠道SD ...

  2. Android应用开发-小巫CSDN博客client之显示博文具体内容

    Android应用开发-小巫CSDN博客客户端之显示博文具体内容 上篇博文给大家介绍的是怎样嵌入有米广告而且获取收益,本篇博客打算讲讲关于怎样在一个ListView里显示博文的具体信息.这个可能是童鞋 ...

  3. Android应用开发-小巫CSDN博客client之获取评论列表

    Android应用开发-小巫CSDN博客客户端之获取评论列表 上一篇博客介绍了博文具体内容的业务逻辑实现,本篇博客介绍小巫CSDN博客客户端的最后一项功能.获取评论列表,这个功能的实现跟前面获取文章列 ...

  4. Android应用开发-小巫CSDN博客客户端开发开篇

    2014年9月8日 八月十五 祝各位中秋节快乐 小巫断断续续花了几个星期的时间开发了这么一款应用——小巫CSDN博客,属于私人定制的这样的一款应用,整个客户端的数据全部来自本人博客,是通过爬取本人博客 ...

  5. 基于Netbeans的安卓Android开发环境配置 - CSDN博客

    原文:基于Netbeans的安卓Android开发环境配置 - CSDN博客 基于Netbeans的安卓Android开发环境配置 一.准备工作 NetBeans 勾选网页中的Accept-选择对应系 ...

  6. iOS开发的知名大牛博客小汇

    王巍的博客:王巍目前在日本横滨任职于LINE.工作内容主要进行Unity3D开发,8小时之外经常进行iOS/Mac开发.他的陈列柜中已有多款应用,其中番茄工作法工具非常棒.http://onevcat ...

  7. 小议common lisp程序开发流程 - Ever 17 - 博客频道 - CSDN.NET

    小议common lisp程序开发流程 - Ever 17 - 博客频道 - CSDN.NET 小议common lisp程序开发流程 分类: lisp 2011-04-17 20:59 1316人阅 ...

  8. 敏捷开发用户故事系列之十一:CSDN博客用户故事分析

    这是敏捷开发用户故事系列的第十一篇.(栏目目录) 经常有人问起有没有完整的用户故事案例.本人在网上找了一下,大约能找到两三篇,但多数只是为了描述用户故事的语法而已,都不涉及用户故事的颗粒度.大量故事的 ...

  9. 安卓开发:简单的登陆跳转_APK实现直接跳转到本CSDN博客

    最近在开始接触Android APP开发,有了一点java基础之后,安卓代码确实看起来就没有那么难了,可以跟着书上把例程敲一遍,然后熟能生巧可以应用起来,现在写了一个简单的APP,实现的是Edit编辑 ...

随机推荐

  1. [置顶] PMBOOK第四版-ITO与数据流图总结

    具体文档下载地址: 点击打开文档下载地址 :http://download.csdn.net/detail/lyjluandy/6694205 一.过程组与知识领域表(简图) 二.输入 - 工具 - ...

  2. jstorm简介(转)

    Jstorm是参考storm的实时流式计算框架,在网络IO.线程模型.资源调度.可用性及稳定性上做了持续改进,已被越来越多企业使用 作为commiter和user,我还是非常看好它的应用前景,下面是在 ...

  3. JavaScript快速入门(四)——JavaScript函数

    函数声明 之前说的三种函数声明中(参见JavaScript快速入门(二)——JavaScript变量),使用Function构造函数的声明方法比较少见,我们暂时不提.function func() { ...

  4. c++ char_traits模板类的实现!!!

    本人写过与此相关的两篇博客,一个是<cstring>头文件的实现,还有一个是<cwchar>的实现.这里的char_traits模板类在此基础上实现. 为了方便.将源码一起封装 ...

  5. 28.uva 10891 Game of Sum 记忆化dp

    这题和上次的通化邀请赛的那题一样,而且还是简化版本... 那题的题解      请戳这里 ... #include<cstdio> #include<algorithm> #i ...

  6. 树莓派学习笔记——使用文件IO操作GPIO SysFs方式

    0 前言     本文描写叙述假设通过文件IO sysfs方式控制树莓派 GPIO端口.通过sysfs方式控制GPIO,先訪问/sys/class/gpio文件夹,向export文件写入GPIO编号, ...

  7. iOS 网络错误-分类

    在进行网络数据交换的时候总是遇到各种各样的错误. 这些网络错误是来自client还是server. 我们来梳理一下: 我们将错误分为三个大类 操作系统错误 http请求错误 应用错误 1.操作系统错误 ...

  8. A Very Easy Triangle Counting Game

    题意:在圆上取n个点,相邻两个点之间连线,(注意,n和1相邻),然后所有点对(i ,i+2)相连,问能形成的不同的三角形有多少个? 思路:找规律 n=3,cnt=1; n=4,cnt=8; n=5 c ...

  9. Database Connection Pool Library | Libzdb

    Database Connection Pool Library | Libzdb A small, easy to use Open Source Database Connection Pool ...

  10. android打包apk时混淆遇到的问题

    android打包apk的时候一般会选择混淆,而在eclipse中常使用的是proguard来混淆.有很多时候引用了第三方包的时候会导致打包不成功,或者打包成功不能运行的情况. 首先看看正常的prog ...