概述
网络爬虫的工作流程:
1. 模拟浏览器访问网页
2. 从返回的响应数据中抓取关键点或全部数据保存到本地
在java中我们会使用URLConnection 或者 Httpclient 进行一个网页接连,然后给网页发送get或者post方法请求,以获取网页的响应数据,然后再响应数据中抓取到我们需要的东西保存下来。
简单爬取一个网页
首先我们先来完整的爬取一个页面,我们以百度为例:这是百度的网址http://www.baidu.com.
public static void main(String[] args) {
// 定义即将访问的链接
String url = "http://www.baidu.com";![这里写图片描述](http://img.blog.csdn.net/20160519113509113)
// 定义一个字符串用来存储网页内容
StringBuilder result = new StringBuilder(1024);
// 定义一个缓冲字符输入流
BufferedReader in = null;
try {
// 将string转成url对象
URL realUrl = new URL(url);
// 初始化一个链接到那个url的连接
URLConnection connection = realUrl.openConnection();
// 开始实际的连接
connection.connect();
// 初始化 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
// 用来临时存储抓取到的每一行的数据
String line;
while ((line = in.readLine()) != null) {
//遍历抓取到的每一行并将其存储到result里面
result.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
// 使用finally来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
System.out.println(result.toString());
}
运行结果:
我们可以看出已经将百度首页的源码整个爬取了过来。如果只是需要网页中的一部分数据,就可以使用正则匹配获取到相应的数据。
使用正则匹配获取需要数据
还以百度首页为例,我们要获取百度首页的logo图案,下图搜索框上面的图片:
我们已经知道要用正则表达式进行匹配获取,那我们得知道需要匹配什么,使用firefox、chrome或者ie 按F12,查看元素使用选择元素,选中百度logo。
我们可以看到logo的元素代码,我们可以写正则表达式了:<div id=\"lg\"><img hidefocus=\"true\" src=\"(.+?)\"
,正则匹配方法如下:
static String RegexString(String targetStr, String patternStr) {
// 定义一个样式模板,此中使用正则表达式,括号中是要抓的内容
// 相当于埋好了陷阱匹配的地方就会掉下去
Pattern pattern = Pattern.compile(patternStr);
// 定义一个matcher用来做匹配
Matcher matcher = pattern.matcher(targetStr);
// 如果找到了
if (matcher.find()) {
// 打印出结果
return matcher.group(1);
}
return null;
}
在获取到页面数据以后,使用正则匹配方法获取到logo的地址,输出结果如下:
//www.baidu.com/img/bd_logo1.png
使用HttpClient爬取数据
在上面我们都是使用的java自带的URLConnection来实现页面的抓取,单如果是要处理复杂功能,比如重定向的处理,HTML标记的去除,仅仅使用URLConnection还是不够的。这时我们可以使用HttpClient这个第三方jar包。
要使用httpclient,我们首先得加入依赖,可以下载jar,也可以使用maven,maven依赖:
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
以下是使用HttpClient爬去百度首页的一个简单例子:
public static boolean crawlerMethod(String path) throws IOException{
HttpClient httpClient = new HttpClient();
// 设置 HTTP连接超时 5s
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
// 定义输入输出流
InputStream input = null;
OutputStream output = null;
// 得到get 方法
GetMethod getMethod = new GetMethod(path);
// 设置 get请求超时 5s
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
// 设置请求重试处理
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler());
// 执行,返回状态码
int statusCode = httpClient.executeMethod(getMethod);
// 针对状态码进行处理
// 简单起见,只处理返回值为 200 的状态码
if (statusCode == HttpStatus.SC_OK) {
//以流的方式获取数据,还有一种方式是直接获取网页的全部内容 getResponseBody 返回值是byte[]
input = getMethod.getResponseBodyAsStream();
// 通过对URL的得到文件名
String filename = path.substring(path.lastIndexOf('/') + 1)
+ ".html";
// 获得文件输出流
output = new FileOutputStream(filename);
// 输出到文件
int tempByte = -1;
while ((tempByte = input.read()) > 0) {
output.write(tempByte);
}
// 关闭输入流
if (input != null) {
input.close();
}
// 关闭输出流
if (output != null) {
output.close();
}
return true;
}
return false;
}