用Jsoup解析静态网页数据

来源:互联网 发布:软件维护费费用 编辑:程序博客网 时间:2024/06/03 09:15
在个人开发中,很多人都会遇到这样的问题:我有了一个好想法,但是却没有数据源,有时找到了数据,但是那是人家的数据,你没有接口.
这时候你会不会像看着肉却不能吃的那种干着急呢.现在告诉你一个好工具Jsoup,它能够帮我们把人家的网页数据窃取出来,不过Jsoup
有个缺陷,就是只能解析静态的网页数据,对于动态的数据,那是无能为力.还有窃取数据是有被告的风险的,所以呢,不要把人家未授权
的数据用作商业用途.还有就是这是解析的数据,万一某天人家的网页结构更改了,你也就无法再获取数据了,这时候你的程序就有可能出现崩溃哦。当然你也可以根据新的网页结构重新编写解析代码,再次获取数据。
  1.首先要学会Html的Dom结构
   关于Html的Dom的讲解,在W3school上有比较全面的讲解,常用方法有:
         Document.getElementById(String id)返回带有指定ID的元素
         Document.getElementsByClass(String className) :返回包含带有指定类名的所有元素的节点列表.
         Document.getElementsByTagName(String tag) :返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)
   对于Elements,我们可以通过select(String tag)获取Elements下的子节点集合Elements.
  Elements可以通过get(int index)获取集合的特定节点,获取到特定节点后我们可以调用节点的text()方法,就可以获取节点包含的文字内容.
  如果要获取节点的内部属性:比如说href,bgcolor等.我们可以使用节点的attr(String属性)来取得。
  还有一些节点的方法比如说:child(int index)获取特定节点的特定子节点 
                                                      children():特定节点的获取所有子节点
                         
  2.分析网页的Html结构
  找到你要的网页数据,鼠标右键查看元素,这时候就会弹出Html的代码。这时候我们就可以分析观察它的结构了。最重要的是把获取的 Document的文本打印到   控制台,看看数据是否在里面,要不然就是白忙活了.毕竟有些是动态的数据。


我们可以看到一个<tbody></tbody>包含了很多个<tr节点,这些内容就在<td节点的子节点<a里面。 我们可以看到<tr的节点的class属性都是一样的,我们可以很轻易地获取所有的<tr节点;接下来呢就要获取内容所在的<td节点了.这里只有第1和第2个节点有内容(下标是从0开始的),所以只获取它们就好了;接着取出<a节点的文本内容和href属性,因为我们要获取新闻条对应的内容.

3.最后就是解析你的数据了.
  首先获取Jsoup的jar包,这个网上可以下载.
  获取Document对象,有两种方法。
    1.Jsoup.connect(String url).timeout(int millis).get();
    2.你可以通过HttpGet(String url)取得Html的实体.然后通过Jsoup.parse(String html)获得对应的Document对象
  获取玩了就回到开始的解析数据的方法,然后就是得到你想要的数据了。

下面是我解析的例子,你们也可以参考张鸿洋大牛的博客,至于动态的网页解析你们自己去探索吧。

import java.io.IOException;import java.util.ArrayList;import java.util.List;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import android.content.ContentValues;import android.database.sqlite.SQLiteDatabase;import android.os.AsyncTask;import android.util.Log;import com.shite.jobsmile_adapter.NewsAdapter;import com.shite.jobsmile_db.CampusNewsBase;import com.shite.jobsmile_modle.News;/** * 解析学校网页新闻的异步类 *  * @author HuberJobs *  */public class NewsAsyncTask extends AsyncTask<Void, Void, List<News>> {private NewsAdapter adapter;private String table;private CampusNewsBase campusNewsBase;private SQLiteDatabase newsWriter;public NewsAsyncTask(NewsAdapter adapter, CampusNewsBase campusNewsBase, String table) {this.adapter = adapter;this.table =table;this.campusNewsBase = campusNewsBase;}public NewsAsyncTask(NewsAdapter adapter) {this.adapter = adapter;}//获取新闻的同时更新数据库@Overrideprotected List<News> doInBackground(Void... params) {String URL = "http://xc.hfut.edu.cn/120/list.htm";List<News> newsList = new ArrayList<News>();Document doc;newsWriter = campusNewsBase.getWritableDatabase();newsWriter.delete(table, null, null);try {doc = Jsoup.connect(URL).timeout(3000).get();// 拿到<tr>节点集,每个<tr>节点包含了一条新闻标题和日期Elements elements = doc.getElementsByClass("articlelist2_tr");for (Element links : elements) {// 取得每条新闻的标题日期和资源地址String news_title = links.select("td").get(1).text();String news_date = links.select("td").get(2).text();String news_href = links.select("td").get(1).child(0).attr("href");//新闻写入数据库ContentValues newsValues = new ContentValues();newsValues.put("news_title", news_title);newsValues.put("news_date", news_date);newsValues.put("news_href", news_href);newsWriter.insert(table, null, newsValues);//新闻对象News news = new News();news.setTitle(news_title);news.setTime(news_date);news.setUrl(news_href);newsList.add(news);}Log.i("ListData", newsList.size() + ".....");} catch (IOException e) {e.printStackTrace();}finally{newsWriter.close();}return newsList;}@Overrideprotected void onPostExecute(List<News> result) {super.onPostExecute(result);adapter.setNewsData(result);adapter.notifyDataSetChanged();System.out.println("网络操作。。。");}}



0 0