Android应用开发-小巫CSDN博客客户端Jsoup篇
距上一篇博客已经过去了两个星期,小巫也觉得非常抱歉,因为在忙着做另外一个项目,几乎抽不出空来,这不小巫会把剩下的博文全部在国庆补上。本篇博客将会给大家介绍如何使用Jsoup这个库来解析我们的网页,并且如何对我们想解析的网页进行分析。
笔者这里使用的jsoup-1.7.2
下载完之后复制到项目中的libs目录下即可:
对这个库的使用笔者也不是非常熟悉,就只是简单参考了文档而完成了解析工作,所以下面的笔者的解析代码也只是提供参考,具体的解析方法,请认真查看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;
}
小巫已经把解析html的思路告诉大家啦,剩下如何来学习jsoup这个库解析html就靠你们自己去做了。下一篇博客预告,集成友盟社会化组件,详细给大家介绍如何集成友盟提供的社会化组件SDK。
分享到:
相关推荐
CSDN-Blog-Client, 小巫CSDN博客客户端,CSDN人气博主——小巫的倾情之作。
本文将深入剖析“小巫CSDN博客客户端源码”,帮助读者理解Android应用开发的基本原理,特别是针对CSDN博客接口的调用与模拟客户端的实现。 首先,"小巫CSDN博客客户端源码"是一个基于Eclipse开发的项目,这表明它是...
【Android小巫CSDN博客客户端源码】是一款基于Android平台的应用程序,旨在为用户提供一个方便的途径来阅读和浏览CSDN博客上的文章。这个源码是开发者小巫分享的,供其他开发者学习和参考,以提升Android开发技能。 ...
综上所述,【Android开发小巫新闻客户端】项目涵盖了Android应用开发的多个核心领域,涉及了从UI设计到网络请求、数据处理、性能优化等一系列技术点。通过这个项目,开发者不仅可以提升Android开发技能,还能深入...
Android应用--简、美音乐播放器原型放送(作者:小巫) - 巫_1曲待续 Android应用--简、美音乐播放器原型放送(作者:小巫) - 巫_1曲待续
1. **Android SDK**:Android应用开发的基础是Android Software Development Kit (SDK),它包含了开发、测试和调试Android应用所需的所有工具。开发者需要熟悉Android Studio,这是一个集成开发环境(IDE),提供了...
小巫新闻客户端的开发涵盖了移动应用开发的多个重要环节,包括界面设计、网络通信、数据解析、数据库操作以及用户体验优化。通过这样的项目,开发者能够全面了解并掌握Android应用开发的流程和技术栈,同时也展示了...
【小巫新闻客户端完整源代码】是一个公开的项目,它提供了小巫博主开发的新闻客户端应用的全部源码。这个项目对于学习移动应用开发,尤其是对Android或iOS平台有兴趣的开发者来说,是一份宝贵的参考资料。小巫博主在...
这是我的博客参考的代码,我一并上传,大家参考起来比较方便,同时不要积分,互相借鉴! 我的博客链接:http://blog.csdn.net/u012320459/article/details/47373893
总的来说,"小巫新闻客户端底部菜单实现"是一个学习Android应用开发中底部导航菜单的好资源,可以帮助开发者掌握这一常见UI组件的使用。通过阅读和分析源代码,可以深入了解`BottomNavigationView`的工作原理,以及...
小巫新闻客户端开发所有文件,项目源代码+服务端代码+数据库文件
A-week-to-develop-android-app-plan 一周开发Android App计划 ##首批参与成员 -小巫 -墨香 -梦痕 -边城刀客 -徐cc ##要求 -每位认领者按照开源规范来做,代码规范和Android开发规范 -每位认领者必须拥有github账号...
【Android游戏开发基础】 在Android平台上开发游戏,如“疯狂连连看”,首先需要掌握的是Java语言,因为Android SDK主要使用Java作为开发语言。对于初学者,理解面向对象编程的概念,如类、对象、继承、多态等是必...
《Android应用开发详解》 Android App,作为全球最受欢迎的移动操作系统平台之一,为开发者提供了丰富的功能和无限的创新可能。Android应用通常由一系列组件构成,包括活动(Activity)、服务(Service)、广播接收...
在Android应用开发中,图片加载是一个非常重要的环节,特别是在处理大量图片或者网络图片时,高效、内存友好的图片加载框架显得尤为关键。`ImageLoader`就是这样一个被广泛使用的第三方开源框架,它为开发者提供了...
在Android应用开发中,侧滑菜单(Sliding Menu)是一种常见的设计模式,它允许用户通过从屏幕边缘向内滑动来展示或隐藏一个侧边栏,通常包含导航选项或者设置等。这种设计使得用户能够在不离开当前界面的情况下访问...
通过阅读博客和查看提供的DateTimePicker源码,我们可以学习到如何将理论知识转化为实际应用,进一步提升Android开发能力。 总的来说,自定义日期选择器是Android开发中的一个重要实践,它涉及到了Android UI设计、...