曾几时,我仍是一个屌丝,一个在校大学生,高中的时候老师就对咱们撒了一个慌,说...。人们称它为一个善意的谎话,我却傻傻信觉得正。高三的时候努力拼搏了一段时间,惋惜命运老是爱做弄人,高考考到了一个二流的大学,今后我告别了家乡,踏上了大学校门,来到了一个鸟不生蛋但会拉屎的地方。刚来大学的时候,大一浑浑噩噩的度过,大门不错,二门不迈,总体呆在宿舍打游戏,打了大半年的游戏,就那样,大学里最美好的日子离我远去。往事不堪回首,过了一年,现在已经是学长了,做为一个学长,我不甘落后,因而乎上课努力听讲,下课没事和同窗去打球或是去图书馆学习html,css,javascript,java,过着四点一线的生活,在大二一年里拿了两次奖学金。现在,已是大三...,时间还在流逝,如今仍是个屌丝,一个苦逼的大学生,还有事没事喜欢爬各类网站,来知足本身那点小小的虚荣心...。好了,扯淡时间过,该写代码了。javascript
原谅我那点发自心里的扯淡。下面咱们开始进入今天的主题,HTML解析和网络爬虫。css
什么是html,网络爬虫?html
什么是html这里就很少说了,那么什么是网络爬虫呢?是否是在网络上怕的虫?哈哈,简直是弱爆了,在前面扯淡的内容中提到了,我喜欢爬各类网站,我爬过我学校的官网和教务管理系统,爬过各类IT网站,作了个简单的新闻客户端。网络爬虫实际上是指自动地抓取万维网信息的程序或者脚本,或者说是动态地抓取网站数据的程序。java
怎样解析html?android
这里咱们经过Java解析html的利器Jsoup解析html,使用jsoup轻松搞定html解析,让你从一个从矮穷挫瞬间变身高大上,高端大气上档次。编程
为何要解析html?json
咱们都知道如今网络数据传输有三种经常使用的形式,xml,json(【JSON解析】JSON解析高手)和html,咱们的客户端请求服务器,服务器一般给咱们返回上面三种形式的数据。同时若是是我的开发,因为没有本身的服务器,那么咱们开发的应用程序就能够经过爬别人的网站解析html获得咱们要的数据,固然,这种方式获得的数据不推荐,同时也存在太多的局限了,如:受网站的限制,解析困难等等。固然看了这篇文章解析就不是困难了,呵呵。浏览器
jsoup介绍:服务器
jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套很是省力的API,可经过DOM,CSS以及相似于jQuery的操做方法来取出和操做数据。网络
主要功能:
jar包下载(两种方式):
jsoup更多信息查看官网:http://jsoup.org
新建一个Android项目(编码设为UTF-8),将下载的jsoup的jar包添加到项目的libs目录下,并添加到构建路径中,这里因为不打算开发一个完整的应用,因此用的开发工具是咱们更熟悉的eclipse,简单点,不用Android Studio(as),用as也同样。
做为测试数据,咱们来爬一下这个网站:http://it.ithome.com/
访问这个网站,能够看到如今最新的页面显示以下,固然,它的文章会不断更新,这是写文章的时候的页面(页面的一部分):
咱们的任务是把文章的相关信息抓下来,包括:
以下图:
OK,肯定好了咱们要抓取的信息后,咱们经过浏览器调试工具Firebug打开查看该页面的源码找到咱们关心数据的部分:
这个ul里面的li第一个不是咱们想要的数据外,其余的每一个li中都保存了一篇文章的信息。选择其中两个看看。
下面咱们能够编写解析代码了。
第一步:新建JavaBean,Article.java
package com.jxust.lt.htmlparse; /** * 文章bean * @author lt * */ public class Article { private String title; // 标题 private String summary; // 文章内容简介 private String imageUrl; // 图片url private String tags; // 关键子 private String postime; // 发表时间 // setter... // getter... @Override public String toString() { return "Article [title=" + title + ", summary=" + summary + ", imageUrl=" + imageUrl + ", tags=" + tags + ", postime=" + postime + "]"; } }
第二步:新建一个工具类,HtmlParseUtil.java,写一个链接网络并解析返回的html页面的方法:
/** * 请求网络加载数据获得文章的集合 * @param url:网站url */ public static List<Article> getArticles(String url){ List<Article> articles = new ArrayList<Article>(); Connection conn = Jsoup.connect(url); try { // 10秒超时时间,发起get请求,也能够是post Document doc = conn.timeout(10000).get(); // 1. 只要咱们关心的信息数据,这里使用css类选择器 Element ul = doc.select(".ulcl").get(0); // 2. 获得全部的li,排除个别不是同种类型的数据 Elements lis = ul.getElementsByTag("li"); for(int i=1;i<lis.size();i++){ // 经过FileBug发现这个网页里面第一个li不是咱们要的类型,因此从1开始 Article article = new Article(); Element li = lis.get(i); // 数据1,获得图片的url,经过img标签的src属性得到 Element img = li.getElementsByTag("img").first(); // 获取标签的属性值,参数为属性名称 String imageUrl = img.attr("src"); // 数据2,获得文章的标题 Element h2 = li.getElementsByTag("h2").first(); // 取h2元素下面的第一个a标签的文本即为标题 String title = h2.getElementsByTag("a").first().text(); // 数据3,获得文章的发表时间,取h2元素下面的第一个span标签的文本即为文章发表时间 String postime = h2.getElementsByTag("span").first().text(); // 数据4,获得文章内容简介,取li下面第一个p标签的文本 String summary = li.getElementsByTag("p").first().text(); // 数据5,获得文章的关键字,取li下面的class为tags的第一个元素的全部的a标签文本 Element tagsSpan = li.getElementsByClass("tags").first(); Elements tags = tagsSpan.getElementsByTag("a"); String key = ""; for(Element tag : tags){ key+=","+tag.text(); } // 去掉key的第一个","号 key = key.replaceFirst(",", ""); article.setTitle(title); article.setSummary(summary); article.setImageUrl(imageUrl); article.setPostime(postime); article.setTags(key); articles.add(article); } } catch (Exception ex) { ex.printStackTrace(); } return articles; }
在清单文件下添加请求网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
说明:请求网络获得Document对象后(不要导出包,是jsoup下的),经过select()方法帅选了class为ulcl的ul元素,该页面下只有一个class为ulcl,ul下面第一个li不是咱们要的,排除,而后获得每一个li对象,每一个li元素包含一篇文章的信息,解析重要方法说明:
有js的DOM及JQuery编程经验的人应该很容易理解上面的方法,更多的方法信息使用查看Jsoup官网文档。
第三步:测试解析结果:
使用android单元测试:
<instrumentation android:targetPackage="com.jxust.lt.htmlparse" android:name="android.test.InstrumentationTestRunner"></instrumentation>
<uses-library android:name="android.test.runner"/>
新建一个测试类HtmlParseTest.java继承AndroidTestCase
写一个测试方法:
public void testParseHtml(){ List<Article> articles = HtmlParseUtil.getArticles(url); for(int i=0;i<articles.size();i++){ Log.e("result"+i, articles.get(i).toString()); } }
这里的url的值为:"http://it.ithome.com/"
打开模拟器运行测试方法 Run As Android JUnit Test
日志输出结果:
...
能够看到咱们获得了20条数据,咱们来看看其中的一条
能够看到文章标题,内容简介,图片url,关键字,发表时间5个咱们关心的数据全都解析出来了。到这里html解析结束了,如今咱们有了数据,那么咱们就能够将数据显示在listView中了(这里不会将数据显示在ListView中,这个很简单,一个布局一个适配器就搞定了,不懂的能够问),从而能够本身为网站写个新闻客户端了,把要的数据全都抓取下来,体验一下将别人的数据为我所用的快乐,呵呵。
总结一下:
jsoup解析html的步骤:
使用Document.select()进行初步筛选数据
使用Element的一系列方法筛选出咱们要的数据
注意:要对照页面源码解析,解析任何数据以前咱们都得先知道要解析数据的结构,看着html页面的源码调用Document,Element等对象的相关方法怎么简单怎么解析。
jsoup的get和post请求网络在实际运用中使用很少,一般我会将jsoup和Volley,XUtils,Okhttp等著名的android网络框架结合使用,即请求网络用Volley等框架,解析用Jsoup,至少我就是这样作的。