在我的前两篇博客中,介绍了如何通过url下载页面以及对页面中的链接进行解析。
传送门如下:
在这篇博客中,我将结合之前的两个用例,完成一个能从初始链接持续爬取互联网资源的简单爬虫。
修改了第一篇博客的一些地方:
首先,由于直接使用url并不能直接访问到网络上的一些资源,所以就改成了使用httpurlconnection访问,并为此新建了一个HttpPageDownload类。
并将下载的页面按照文件夹路径存放了,并且通过读取页面编码来采用对应的编码下载页面,解决了乱码问题。
核心部分代码如下:
url = new URL(urlStr);
httpConn = (HttpURLConnection) url.openConnection();
// 设置链接超时为5秒
httpConn.setConnectTimeout(5000);
// 设置读取数据超时为30秒
httpConn.setReadTimeout(30000);
// HttpURLConnection.setFollowRedirects(true);
httpConn.setRequestMethod("GET");
// 设置http协议头
httpConn.setRequestProperty("User-Agent",
"Mozilla/4.0(compatible; MSIE 6.0; Windows 2000)");
就是从url获取链接,然后设置链接超时和读取数据超时(可以保证程序不“卡”在某个地方),设置协议头(这样可以让爬虫“看起来”是从浏览器访问的)。
也修改了第二篇博客的一些地方:
将判断绝对地址的方式改为了使用正则表达式判断,部分代码如下:
Pattern p2 = Pattern.compile("(\\w+\\.){2}\\w+");
Matcher m2 = p2.matcher(link);
if (!m2.find()) {
link = "http://" + url.getHost()
+ (url.getPort() == -1 ? "" : ":" + url.getPort())
+ link;
}
在爬虫中主要使用了两个set集合,其中一个为LinkedHashSet用于保存待下载的页面,另一个为HashSet,用于保存已经下载过的集合。
爬虫核心代码如下:
package csdnBlog;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* 简单的网络爬虫,主要实现了页面下载和页面中链接的解析
*
* @author <span style="color:blue"><b>胡征南</b></span>
*
*/
public class Spider1 {
// 用于维护当前队列的Set集合
private static Set<String> links = new LinkedHashSet<String>();
// 用于判断是否重复的Set集合
private static Set<String> linkPool = new HashSet<String>();
/**
* 爬的核心方法
*
* @param url
* 初始地址
*/
public static void crawl(String url) {
links.add(url);
linkPool.add(url);
int solvedLink = 0;
int succeed = 0;
int failed = 0;
while (!links.isEmpty()) {
// 从队列中获取一个连接,并下载该页面
System.out.println("1/4.当前队列中链接数量:" + links.size());
String currentUrl = links.iterator().next();
System.out.println("2/4.当前正在下载的页面为:" + currentUrl);
links.remove(currentUrl);
boolean downloadResult = HttpPageDownload.DownloadPages(currentUrl);
// 分析页面中的链接,并将它们放到队列里
if (downloadResult) {
System.out.println("3/4.页面下载成功,正在解析。。。");
ArrayList<String> tmpUrlList = RetrieveLinks
.retrieveLinks(currentUrl);
for (String string : tmpUrlList) {
if (!linkPool.contains(string)) {
linkPool.add(string);
// 在此处可以采取一些策略选择链接
links.add(string);
}
}
System.out.println("4/4.页面解析完成!");
succeed++;
} else {
System.err.println("页面下载失败,失败页面的连接地址为:\n" + currentUrl + "\n");
failed++;
}
solvedLink++;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("已处理完成链接:" + solvedLink + ", 其中成功:" + succeed
+ ", 失败" + failed + ",当前时间:" + sdf.format(new Date()));
}
System.out.println("完成此次爬虫任务!");
}
public static void main(String[] args) {
Spider1.crawl("http://www.163.com/");
}
}
再结合前两篇博客的例子(通过简单拷贝粘贴),就已经完成了一个简单的爬虫!
但是这还只是一只不知道要做什么,只知道乱来的爬虫,在以后的博客中,我得教会它往哪里走,爬取一些真正需要的资源。
相关代码资源下载地址:http://download.csdn.net/detail/huzhengnan/7203185