原谅我那点发自内心的扯淡。下面我们开始进入今天的主题,html解析和网络爬虫。
什么是html,网络爬虫?
什么是html这里就不多说了,那么什么是网络爬虫呢?是不是在网络上怕的虫?哈哈,简直是弱爆了,在前面扯淡的内容中提到了,我喜欢爬各种网站,我爬过我学校的官网和教务管理系统,爬过各种it网站,做了个简单的新闻客户端。网络爬虫其实是指自动地抓取万维网信息的程序或者脚本,或者说是动态地抓取网站数据的程序。
怎样解析html?
这里我们通过java解析html的利器jsoup解析html,使用jsoup轻松搞定html解析,让你从一个从矮穷挫瞬间变身高大上,高端大气上档次。
为什么要解析html?
我们都知道现在网络数据传输有三种常用的形式,xml,json(【json解析】json解析高手)和html,我们的客户端请求服务器,服务器通常给我们返回上面三种形式的数据。同时如果是个人开发,由于没有自己的服务器,那么我们开发的应用程序就可以通过爬别人的网站解析html得到我们要的数据,当然,这种方式得到的数据不推荐,同时也存在太多的局限了,如:受网站的限制,解析困难等等。当然看了这篇文章解析就不是困难了,呵呵。
二、jsoup和资源准备jsoup介绍:
jsoup 是一款java 的html解析器,可直接解析某个url地址、html文本内容。它提供了一套非常省力的api,可通过dom,css以及类似于jquery的操作方法来取出和操作数据。
主要功能:
从一个url,文件或字符串中解析html;
使用dom或css选择器来查找、取出数据;
可操作html元素、属性、文本;
jar包下载(两种方式):
官网下载最新版:http://jsoup.org/download
jsoup-1.8.3.jar(jar,doc和源码)
jsoup更多信息查看官网:http://jsoup.org
三、html解析实战 新建一个android项目(编码设为utf-8),将下载的jsoup的jar包添加到项目的libs目录下,并添加到构建路径中,这里由于不打算开发一个完整的应用,所以用的开发工具是我们更熟悉的eclipse,简单点,不用android studio(as),用as也一样。
作为测试数据,我们来爬一下这个网站:http://it.ithome.com/
访问这个网站,可以看到现在最新的页面显示如下,当然,它的文章会不断更新,这是写文章的时候的页面(页面的一部分):
我们的任务是把文章的相关信息抓下来,包括:
文章左边的图片url
文章的标题article
文章的内容简介summary
底部的关键字tags
右上角的发表时间postime
如下图:
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元素包含一篇文章的信息,解析重要方法说明:
document.select(string cssquery):通过css选择器获取e元素集elements
element.getelementsbytag(string tagname):通过标签名称获取元素elements
element.getelementsbyclass(string classname):通过标类选择器获取元素elements
element.getelementbyid(string id):通过id获取元素element
element.attr(string attrname):通过属性名获取属性值
element.text():获取标签元素的文本
有js的dom及jquery编程经验的人应该很容易理解上面的方法,更多的方法信息使用查看jsoup官网文档。
第三步:测试解析结果:
使用android单元测试:
在androidmanifest.xml添加instrumentation
<instrumentation android:targetpackage="com.jxust.lt.htmlparse" android:name="android.test.instrumentationtestrunner"></instrumentation>
在androidmanifest.xml添加use-library
<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对象:
通过发送jsoup的get或者post请求返回document对象
将html字符串转换成document对象(通过jsoup.parse()方法):
使用document.select()进行初步筛选数据
使用element的一系列方法筛选出我们要的数据
注意:要对照页面源码解析,解析任何数据之前我们都得先知道要解析数据的结构,看着html页面的源码调用document,element等对象的相关方法怎么简单怎么解析。
jsoup的get和post请求网络在实际运用中使用不多,通常我会将jsoup和volley,xutils,okhttp等著名的android网络框架结合使用,即请求网络用volley等框架,解析用jsoup,至少我就是这样做的。
以上就是html解析网络爬虫图文介绍的详细内容。