用Jsoup解析静态网页数据
2015-07-19 11:08
561 查看
在个人开发中,很多人都会遇到这样的问题:我有了一个好想法,但是却没有数据源,有时找到了数据,但是那是人家的数据,你没有接口.
这时候你会不会像看着肉却不能吃的那种干着急呢.现在告诉你一个好工具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的文本打印到 控制台,看看数据是否在里面,要不然就是白忙活了.毕竟有些是动态的数据。
![](http://img.blog.csdn.net/20150719164112302?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
我们可以看到一个<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对象
获取玩了就回到开始的解析数据的方法,然后就是得到你想要的数据了。
下面是我解析的例子,你们也可以参考张鸿洋大牛的博客,至于动态的网页解析你们自己去探索吧。
这时候你会不会像看着肉却不能吃的那种干着急呢.现在告诉你一个好工具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("网络操作。。。"); } }
相关文章推荐
- seajs的使用方法个人总结
- JavaScript中的Array对象方法调用
- JavaScript——递归,嵌套和闭包
- javascript获取网页宽高方法汇总
- ejs笔记
- 北风网149 javaScript
- preInterview_javaScript
- javaScript标签全称与插件
- js 选项卡实现
- JavaScript.笔记
- JavaScript中的Math方法演示
- 创建你的第一个JavaScript库
- 交换两个变量,不使用第三个变量(js向)
- Creating your own JavaScript Library
- JavaScript中的Boolean 方法与Number方法
- 使用JavaScript定时刷新,请求响应时间慢慢变长
- JavaScript BOM浏览器对象模型
- JS基础规范
- JSP学习心路
- JSP学习心路