上週接了一個活,在沒有api的狀況下,對一個管理系統的網頁進行移動端開發,由於以前作過一個沒有現成api的項目,因此一開始就用fiddler進行抓包,結果很明顯:什麼都沒有。php
在網上搜索得知Jsoup能夠作到,那就先學學Jsoup怎麼用吧。html
我選擇 http://www.jcodecraeer.com/plus/list.php?tid=18 爲樣本,這個網頁有標題,有描述,有時間,有圖片。。。 很是適合作成listview啊。java
用谷歌內核的瀏覽器訪問網站 按下F12 出現調試工具 發現 該頁面的每個文章 是在 <li class="archive-item clearfix">中 全部的文章是在<ul class="archive-list">中android
而Jsoup就是靠這些信息來幫咱們選定須要的數據json
新建方法 LoadHtml 前面2個參數都是空 由於訪問網址直接在裏面固定了 不須要獲取 第三個參數 返回咱們須要的list就好了api
class LoadHtml extends AsyncTask<Void, Void, List<ArticleBean>>{ ProgressDialog bar; @Override protected List<ArticleBean> doInBackground(Void... params) { List<ArticleBean>articleBeans=new ArrayList<ArticleBean>(); try { Document doc = Jsoup.connect("http://www.jcodecraeer.com/plus/list.php?tid=18").timeout(5000).get(); Element masthead=doc.select("ul.archive-list").first(); //System.out.println("masthead"+masthead.toString()+"masthead"); Elements articleElements=masthead.select("li.archive-item.clearfix"); System.out.println("articleElements"+articleElements.toString()+"articleElements"); for (int i = 0; i < articleElements.size(); i++) { ArticleBean article = new ArticleBean(); Element articleElement=articleElements.get(i); Element titleElement=articleElement.select("h3").first(); System.out.println(titleElement.toString()+"titleElement"); //Elements titleElements=masthead.select("div.archive-detail h3"); Element summaryElement=articleElement.select("div.archive-detail p").first(); //Elements summaryElements=masthead.select("div.archive-detail p"); Element postTimeElement=articleElement.select("div.archive-text div.archive-detail div.archive-data span.glyphicon-class").first(); //Elements postTimeElements=masthead.select("div.archive-detail div.archive-data span.glyphicon-class"); String url="http://www.jcodecraeer.com/" +titleElement.attr("href"); String title=titleElement.text(); String summary=summaryElement.text(); String data=postTimeElement.text(); article.setTitle(title); article.setSummary(summary); article.setData(data); article.setNewsUrl(url); articleBeans.add(article); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return articleBeans; } @Override protected void onPreExecute() { super.onPreExecute(); bar=new ProgressDialog(MainActivity.this); bar.setMessage("waiting"); bar.setIndeterminate(false); bar.setCancelable(false); bar.show(); } @Override protected void onPostExecute(List<ArticleBean> result) { // TODO Auto-generated method stub super.onPostExecute(result); bar.dismiss(); TestAdapter adapter =new TestAdapter(result, getApplicationContext()); listView.setAdapter(adapter); } }
在doInBackground 方法中 使用Jsoup.connect方法訪問網頁 ,獲取到Document對象。瀏覽器
每個文章 是在 <li class="archive-item clearfix">中 全部的文章是在<ul class="archive-list">中架構
先找到整個文章的對象 Element masthead=doc.select("ul.archive-list").first();ide
再從整個文章的對象裏面找到每一個文章的對象 Elements articleElements=masthead.select("li.archive-item.clearfix");工具
看圖能夠發現 咱們須要的數據所有都在裏面 關鍵是如何取出來
我抽取一個 文章 標題在第10行 <h3>標籤裏
內容簡介在第11行 <p>標籤裏
而時間在第34行 <span class="glyphicon-class">標籤裏
一開始我覺得 都要把前面的標籤都放進去 可是不須要 .first()方法是取第一個這種標籤裏面的數據 時間數據 和 觀看人數 的標籤是同樣的 可是人數在前面 因此結果的圖片顯示的人數 而不是時間
標題 Element titleElement=articleElement.select("h3").first();
簡介 Element summaryElement=articleElement.select("p").first();
時間 Element postTimeElement=articleElement.select("span.glyphicon-class").first(); 這麼寫 會顯示最早使用這個標籤的 「人數」
下面的形式也行 不過麻煩多了
簡介 Element summaryElement=articleElement.select("div.archive-detail p").first();
時間使用下面的寫法 才能正確的顯示 」時間「
Element postTimeElement=articleElement.select("div.archive-data span.glyphicon-class").first();
Element postTimeElement=articleElement.select("div.archive-text div.archive-detail div.archive-data span.glyphicon-class").first();
1 <li class="archive-item clearfix"> 2 <a href="/a/anzhuokaifa/androidkaifa/2016/0425/4178.html" title="解讀Android官方MVP項目單元測試"> 3 4 <div class='covercon'> <img src='/uploads/20160425/1461550497774572-lp.png' class='cover imgloadinglater' style='display: block;' /> </div> 5 6 </a> 7 8 <div class="archive-text"> 9 <div class="archive-detail"> 10 <h3><a href="/a/anzhuokaifa/androidkaifa/2016/0425/4178.html" title="解讀Android官方MVP項目單元測試" >解讀Android官方MVP項目單元測試</a></h3> 11 <p>Google在3月份推出了一個項目,用來介紹Android MVP架構的各類組合,能夠認爲是官方在這方面的最佳實踐。使人稱道的是除了MVP自己以外,這些工程配備了極其完善的單元測試用例,學習價值極高。本文着重針對todo-mvp的單元測試進行解讀。 寫在前面 關於MVP 關 </p> 12 <div class="archive-info clearfix"> 13 <ul> 14 <li class="list-user"> 15 <a href="" target="_blank"> 16 <img src="/templets/jcodecraeer/images/iconfont-morentouxiang.png"> 17 <strong>泡在網上的日子</strong> 18 </a> 19 </li> 20 <li class="list-tag"><span><a href='/tags.php?/MVP/' class='tag'>MVP</a>,<a href='/tags.php?/單元測試/' class='tag'>單元測試</a> </span></li> 21 <li class="list-msg"> 22 <span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span> 23 <span class="glyphicon-class">102</span> 24 <span class="glyphicon glyphicon-comment" aria-hidden="true"></span> 25 <span class="glyphicon-class">0</span> 26 <span class="glyphicon glyphicon-bookmark" aria-hidden="true"></span> 27 <span class="glyphicon-class">2</span> 28 </li> 29 30 </ul> 31 </div> 32 <div class="archive-data"> 33 <span class="glyphicon glyphicon-time" aria-hidden="true"></span> 34 <span class="glyphicon-class">16-04-25</span> 35 </div> 36 37 </div> 38 </div> 39 </li><li class="archive-item clearfix">
獲取到對象以後 轉爲 String
String title=titleElement.text();
String summary=summaryElement.text();
String data=postTimeElement.text();
而後設置給bean 最後 return articleBeans;
article.setTitle(title);
article.setSummary(summary);
article.setData(data);
articleBeans.add(article);
Adapter 和 ArticleBean 這些就不說了,怎麼簡單怎麼來,暫時沒設置圖片
1 package com.demon.AJsoup; 2 3 import java.util.List; 4 5 import android.content.Context; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.view.ViewGroup; 9 import android.widget.BaseAdapter; 10 import android.widget.ImageView; 11 import android.widget.TextView; 12 13 public class TestAdapter extends BaseAdapter { 14 15 private List<ArticleBean> mlist; 16 private LayoutInflater mInflater; 17 18 19 public TestAdapter(List<ArticleBean> data, Context context) { 20 mlist = data; 21 mInflater=LayoutInflater.from(context); 22 } 23 24 @Override 25 public int getCount() { 26 // TODO Auto-generated method stub 27 return mlist.size(); 28 } 29 30 @Override 31 public Object getItem(int arg0) { 32 // TODO Auto-generated method stub 33 return mlist.get(arg0); 34 } 35 36 @Override 37 public long getItemId(int arg0) { 38 // TODO Auto-generated method stub 39 return arg0; 40 } 41 42 @Override 43 public View getView(int arg0, View convertView, ViewGroup arg2) { 44 ViewHodler hodler=null; 45 if (convertView==null) { 46 hodler=new ViewHodler(); 47 convertView=mInflater.inflate(R.layout.item, null); 48 hodler.title=(TextView) convertView.findViewById(R.id.title); 49 hodler.summary=(TextView) convertView.findViewById(R.id.summary); 50 hodler.data=(TextView) convertView.findViewById(R.id.data); 51 hodler.iv=(ImageView) convertView.findViewById(R.id.iv); 52 53 convertView.setTag(hodler); 54 } 55 else { 56 hodler=(ViewHodler) convertView.getTag(); 57 } 58 59 hodler.title.setText(mlist.get(arg0).getTitle()); 60 hodler.summary.setText(mlist.get(arg0).getSummary()); 61 hodler.data.setText(mlist.get(arg0).getData()); 62 63 hodler.iv.setImageResource(R.drawable.ic_launcher); 64 65 return convertView; 66 } 67 68 class ViewHodler{ 69 public TextView title,summary,data; 70 public ImageView iv; 71 72 } 73 }
1 package com.demon.AJsoup; 2 3 public class ArticleBean { 4 @Override 5 public String toString() { 6 return "ArticleBean [Title=" + Title + ", Summary=" + Summary 7 + ", Data=" + Data + ", NewsUrl=" + NewsUrl + "]"; 8 } 9 public String getTitle() { 10 return Title; 11 } 12 public void setTitle(String title) { 13 Title = title; 14 } 15 public String getSummary() { 16 return Summary; 17 } 18 public void setSummary(String summary) { 19 Summary = summary; 20 } 21 public String getData() { 22 return Data; 23 } 24 public void setData(String data) { 25 Data = data; 26 } 27 public String getNewsUrl() { 28 return NewsUrl; 29 } 30 public void setNewsUrl(String newsUrl) { 31 NewsUrl = newsUrl; 32 } 33 public String Title; 34 public String Summary; 35 public String Data; 36 public String NewsUrl; 37 38 }
因爲我使用了 ProgressDialog 因此在onPreExecute()方法中 要作下設置
@Override protected void onPreExecute() { super.onPreExecute(); bar=new ProgressDialog(MainActivity.this); bar.setMessage("waiting"); bar.setIndeterminate(false); bar.setCancelable(false); bar.show(); }
在 onPostExecute()方法中 要把ProgressDialog 註銷 並把adapter適配給listview
@Override protected void onPostExecute(List<ArticleBean> result) { super.onPostExecute(result); bar.dismiss(); TestAdapter adapter =new TestAdapter(result, getApplicationContext()); listView.setAdapter(adapter); }
最後 回到oncreate方法中
new LoadHtml().execute();
效果以下 懶得改了 這裏時間顯示成了人數 具體緣由 回去看紅字
寫這篇文章主要是爲了學習一下 jsoup的使用方法 然而開發移動端 通常都會有json
能不能完成那個活 我還不肯定 由於還有登錄這一個難題