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 getBlogItemList(int blogType, String str) {// Log.e("URL---->", str);List list = new ArrayList();// 擷取文檔對象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 getContent(String url, String str) {List list = new ArrayList();// 擷取文檔內容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);// 擷取所有標籤為轉換為 如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");}// 擷取所有標籤為 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 getBlogCommentList(String str, int pageIndex,int pageSize) {List list = new ArrayList();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); // 評論條數// 如果評論數大於20if (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的話,表示它是評論的topiccomment.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。