用Jsoup解析静态网页数据

在个人开发中,很多人都会遇到这样的问题:我有了一个好想法,但是却没有数据源,有时找到了数据,但是那是人家的数据,你没有接口.
这时候你会不会像看着肉却不能吃的那种干着急呢.现在告诉你一个好工具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;
	}

	//获取新闻的同时更新数据库
	@Override
	protected 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;
	}

	@Override
	protected void onPostExecute(List<News> result) {
		super.onPostExecute(result);
		adapter.setNewsData(result);
		adapter.notifyDataSetChanged();
		System.out.println("网络操作。。。");
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值