`
weiyinchao88
  • 浏览: 1234285 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多
Android应用开发-小巫CSDN博客客户端Jsoup篇

距上一篇博客已经过去了两个星期,小巫也觉得非常抱歉,因为在忙着做另外一个项目,几乎抽不出空来,这不小巫会把剩下的博文全部在国庆补上。本篇博客将会给大家介绍如何使用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。



分享到:
评论

相关推荐

    CSDN-Blog-Client, 小巫CSDN博客客户端,CSDN人气博主——小巫的倾情之作。.zip

    CSDN-Blog-Client, 小巫CSDN博客客户端,CSDN人气博主——小巫的倾情之作。

    小巫CSDN博客客户端源码

    本文将深入剖析“小巫CSDN博客客户端源码”,帮助读者理解Android应用开发的基本原理,特别是针对CSDN博客接口的调用与模拟客户端的实现。 首先,"小巫CSDN博客客户端源码"是一个基于Eclipse开发的项目,这表明它是...

    Android小巫CSDN博客客户端源码

    【Android小巫CSDN博客客户端源码】是一款基于Android平台的应用程序,旨在为用户提供一个方便的途径来阅读和浏览CSDN博客上的文章。这个源码是开发者小巫分享的,供其他开发者学习和参考,以提升Android开发技能。 ...

    Android开发小巫新闻客户端.zip_Android开发新闻客户端_android 新闻_小巫_新闻app_新闻客户端

    综上所述,【Android开发小巫新闻客户端】项目涵盖了Android应用开发的多个核心领域,涉及了从UI设计到网络请求、数据处理、性能优化等一系列技术点。通过这个项目,开发者不仅可以提升Android开发技能,还能深入...

    Android应用--简、美音乐播放器原型放送(作者:小巫) - 巫_1曲待续

    Android应用--简、美音乐播放器原型放送(作者:小巫) - 巫_1曲待续 Android应用--简、美音乐播放器原型放送(作者:小巫) - 巫_1曲待续

    Android应用--简、美音乐播放器开发项目

    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:一周开发AndroidApp计划

    A-week-to-develop-android-app-plan 一周开发Android App计划 ##首批参与成员 -小巫 -墨香 -梦痕 -边城刀客 -徐cc ##要求 -每位认领者按照开源规范来做,代码规范和Android开发规范 -每位认领者必须拥有github账号...

    Android游戏-疯狂连连看

    【Android游戏开发基础】 在Android平台上开发游戏,如“疯狂连连看”,首先需要掌握的是Java语言,因为Android SDK主要使用Java作为开发语言。对于初学者,理解面向对象编程的概念,如类、对象、继承、多态等是必...

    一个android app

    《Android应用开发详解》 Android App,作为全球最受欢迎的移动操作系统平台之一,为开发者提供了丰富的功能和无限的创新可能。Android应用通常由一系列组件构成,包括活动(Activity)、服务(Service)、广播接收...

    Android第三方开源框架ImageLoader的完美Demo

    在Android应用开发中,图片加载是一个非常重要的环节,特别是在处理大量图片或者网络图片时,高效、内存友好的图片加载框架显得尤为关键。`ImageLoader`就是这样一个被广泛使用的第三方开源框架,它为开发者提供了...

    Android-侧滑菜单SlidingMen程序文件

    在Android应用开发中,侧滑菜单(Sliding Menu)是一种常见的设计模式,它允许用户通过从屏幕边缘向内滑动来展示或隐藏一个侧边栏,通常包含导航选项或者设置等。这种设计使得用户能够在不离开当前界面的情况下访问...

    Android自定义日期选择器源码

    通过阅读博客和查看提供的DateTimePicker源码,我们可以学习到如何将理论知识转化为实际应用,进一步提升Android开发能力。 总的来说,自定义日期选择器是Android开发中的一个重要实践,它涉及到了Android UI设计、...

Global site tag (gtag.js) - Google Analytics