现在有越来越多的人热衷于做网络爬虫(网络蜘蛛),也有越来越多的地方需要网络爬虫,比如搜索引擎、资讯采集、舆情监测等等,诸如此类。网络爬虫涉及到的技术(算法/策略)广而复杂,如网页获取、网页跟踪、网页分析、网页搜索、网页评级和结构/非结构化数据抽取以及后期更细粒度的数据挖掘等方方面面,对于新手来说,不是一朝一夕便能完全掌握且熟练应用的,对于作者来说,更无法在一篇文章内就将其说清楚。因此在本篇文章中,我们仅将视线聚焦在网络爬虫的最基础技术——网页抓取方面。
说到网页抓取,往往有两个点是不得不说的,首先是网页编码的识别,另外一个是对网页脚本运行的支持,除此之外,是否支持以POST方式提交请求和支持自动的cookie管理也是很多人所关注的重要方面。其实Java世界里,已经有很多开源的组件来支持各种各样方式的网页抓取了,包括上面提到的四个重点,所以说使用Java做网页抓取还是比较容易的。下面,作者将重点介绍其中的六种方式。
HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。
(1)实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
(2)支持自动转向
(3)支持 HTTPS 协议
(4)支持代理服务器
(5)支持自动的Cookies管理等
Java爬虫开发中应用最多的一种网页获取技术,速度和性能一流,在功能支持方面显得较为底层,不支持JS脚本执行和CSS解析、渲染等准浏览器功能,推荐用于需要快速获取网页而无需解析脚本和CSS的场景。
范例代码如下:
package cn.ysh.studio.crawler.httpclient;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
/**
* 基于HtmlClient抓取网页内容
*
* @author www.yshjava.cn
*/
public class HttpClientTest {
public static void main(String[] args)throws Exception{
//目标页面
String url ="http://www.jjwxc.net/";
//创建一个默认的HttpClient
HttpClient httpclient =new DefaultHttpClient();
try{
//以get方式请求网页http://www.yshjava.cn
HttpGet httpget =new HttpGet(url);
//打印请求地址
System.out.println("executing request "+ httpget.getURI());
//创建响应处理器处理服务器响应内容
ResponseHandler responseHandler = new BasicResponseHandler();
//执行请求并获取结果
String responseBody = httpclient.execute(httpget, responseHandler);
System.out.println("----------------------------------------");
String htmlStr=null;
if(responseBody != null) {
// htmlStr=new String(EntityUtils.toString(responseBody));
// htmlStr=new String(htmlStr.getBytes("ISO-8859-1"), "gbk"); // 读取乱码解决
responseBody=new String(responseBody.getBytes("ISO-8859-1"), "gb2312");
}
System.out.println(responseBody);
System.out.println("----------------------------------------");
}finally{//关闭连接管理器
httpclient.getConnectionManager().shutdown();
}
}
}
jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
网页获取和解析速度飞快,推荐使用。
主要功能如下:
1. 从一个URL,文件或字符串中解析HTML;
2. 使用DOM或CSS选择器来查找、取出数据;
3. 可操作HTML元素、属性、文本;
范例代码如下:
package cn.ysh.studio.crawler.jsoup;
import java.io.IOException;
import org.jsoup.Jsoup;
/**
* 基于Jsoup抓取网页内容
* @author www.yshjava.cn
*/
public class JsoupTest {
public static void main(String[] args)throws IOException{
//目标页面
String url ="http://www.jjwxc.net";
//使用Jsoup连接目标页面,并执行请求,获取服务器响应内容
String html =Jsoup.connect(url).execute().body();
//打印页面内容
System.out.println(html);
}
}
htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容。项目可以模拟浏览器运行,被誉为java浏览器的开源实现。这个没有界面的浏览器,运行速度也是非常迅速的。采用的是Rhinojs引擎。模拟js运行。
网页获取和解析速度较快,性能较好,推荐用于需要解析网页脚本的应用场景。
范例代码如下:
package cn.ysh.studio.crawler.htmlunit;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebClient;
/**
* 基于HtmlUnit抓取网页内容
*
* @author www.yshjava.cn
*/
public class HtmlUnitSpider {
public static void main(String[] s) throws Exception {
// 目标网页
String url = "http://www.jjwxc.net/";
// 模拟特定浏览器FIREFOX_3
WebClient spider = new WebClient(BrowserVersion.FIREFOX_3);
// 获取目标网页
Page page = spider.getPage(url);
// 打印网页内容
System.out.println(page.getWebResponse().getContentAsString());
// 关闭所有窗口
// spider.closeAllWindows();
spider.close();
}
}
Watij
package cn.ysh.studio.crawler.ie;
import watij.runtime.ie.IE;
/**
* 基于Watij抓取网页内容,仅限Windows平台
*
* @author www.yshjava.cn
*/
public class WatijTest {
public static void main(String[] s) {
// 目标页面
String url = "http://www.jjwxc.net/";
// 实例化IE浏览器对象
IE ie = new IE();
try {
// 启动浏览器
ie.start();
// 转到目标网页
ie.goTo(url);
// 等待网页加载就绪
ie.waitUntilReady();
// 打印页面内容
System.out.println(ie.html());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {// 关闭IE浏览器
ie.close();
} catch (Exception e) {
}
}
}
}
Selenium也是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Mozilla Suite等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建衰退测试检验软件功能和用户需求。支持自动录制动作和自动生成。Net、Java、Perl等不同语言的测试脚本。Selenium 是ThoughtWorks专门为Web应用程序编写的一个验收测试工具。
网页获取速度较慢,对于爬虫来说,不是一个好的选择。
范例代码如下:
package cn.ysh.studio.crawler.selenium;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
/**
* 基于HtmlDriver抓取网页内容
*
* @author www.yshjava.cn
*/
public class HtmlDriverTest {
public static void main(String[] s) {
// 目标网页
String url = "http://www.jjwxc.net/";
HtmlUnitDriver driver = new HtmlUnitDriver();
try {
// 禁用JS脚本功能
driver.setJavascriptEnabled(false);
// 打开目标网页
driver.get(url);
// 获取当前网页源码
String html = driver.getPageSource();
// 打印网页源码
System.out.println(html);
} catch (Exception e) {
// 打印堆栈信息
e.printStackTrace();
} finally {
try {
// 关闭并退出
driver.close();
driver.quit();
} catch (Exception e) {
}
}
}
}
Webspec 一个开源的带有界面的Java浏览器,支持脚本执行和CSS渲染。速度一般。
范例代码如下:
package cn.ysh.studio.crawler.webspec;
import org.watij.webspec.dsl.WebSpec;
/**
* 基于WebSpec抓取网页内容
*
* @author www.yshjava.cn
*/
public class WebspecTest {
public static void main(String[] s){
//目标网页
String url ="http://www.jjwxc.net/";
//实例化浏览器对象
WebSpec spec =new WebSpec().mozilla();
//隐藏浏览器窗体
spec.hide();
//打开目标页面
spec.open(url);
//打印网页源码
System.out.println(spec.source());
//关闭所有窗口
spec.closeAll();
}
}