在爬虫开发中,常用的语言是python,但是也可以使用java来进行 开发,这样就可以利用java强大的库,下面就来介绍一下常用的java爬虫框架。
Crawler4j
定制Controller层,用于控制爬虫的行为
使用main()直接开始程序即可
下面上代码:
// 此类用于控制爬虫爬取网页的图片,并且将图片存储在本地
public class ImageCrawler extends WebCrawler {
// 用于过滤,使用正则表达式匹配
private static final Pattern filters = Pattern.compile(
".*(\\.(css|js|mid|mp2|mp3|mp4|wav|avi|mov|mpeg|ram|m4v|pdf" +
"|rm|smil|wmv|swf|wma|zip|rar|gz))$");
// 用于确定需要爬取的资源类型(这边是爬取图片)
private static final Pattern imgPatterns = Pattern.compile(".*(\\.(bmp|gif|jpe?g|png|tiff?))$");
// 存储图片的文件夹
private static File storageFolder;
// 爬虫会爬取的域,可以是一个普通的URL
private static String[] crawlDomains;
// 初始化Controller
public static void configure(String[] domain, String storageFolderName) {
crawlDomains = domain;
storageFolder = new File(storageFolderName);
if (!storageFolder.exists()) {
storageFolder.mkdirs();
}
}
@Override
// 确定需不需要下载url所指定的资源
public boolean shouldVisit(Page referringPage, WebURL url) {
String href = url.getURL().toLowerCase();
// 和过滤器相匹配,不下载
if (filters.matcher(href).matches()) {
return false;
}
// 是图片,下载
if (imgPatterns.matcher(href).matches()) {
return true;
}
// 如果是网页,进行url匹配,看是不是在需要下载的域内部
for (String domain : crawlDomains) {
// 在需要下载的域内
if (href.startsWith(domain)) {
return true;
}
}
return false;
}
// shouldVisit为true,则会调用此函数
@Override
public void visit(Page page) {
String url = page.getWebURL().getURL();
// 如果是图片,并且图片大小在10kb以内,就不访问
if (!imgPatterns.matcher(url).matches() ||
!((page.getParseData() instanceof BinaryParseData) ||
(page.getContentData().length < (10 * 1024)))) {
return;
}
// get a unique name for storing this image
// 获取图片的格式
String extension = url.substring(url.lastIndexOf('.'));
// 获取图片的名称,此处是随机值
String hashedName = UUID.randomUUID() + extension;
// 存储图片
String filename = storageFolder.getAbsolutePath() + "/" + hashedName;
try {
// 写入文件系统,并且输出到磁盘
Files.write(page.getContentData(), new File(filename));
logger.info("Stored: {}", url);
} catch (IOException iox) {
logger.error("Failed to write file: " + filename, iox);
}
}
}
下面是启动爬虫所用:
public class ImageCrawlController {
private static final Logger logger = LoggerFactory.getLogger(ImageCrawlController.class);
public static void main(String[] args) throws Exception {
// 爬虫参数控制,需要传入3个参数
// 存储路径,这个是存储爬虫的运行时数据的
// 并行线程数量
// 图片存储路径
if (args.length < 3) {
logger.info("Needed parameters: ");
logger.info("\t rootFolder (it will contain intermediate crawl data)");
logger.info("\t numberOfCralwers (number of concurrent threads)");
logger.info("\t storageFolder (a folder for storing downloaded images)");
return;
}
String rootFolder = args[0];
int numberOfCrawlers = Integer.parseInt(args[1]);
String storageFolder = args[2];
CrawlConfig config = new CrawlConfig();
// 设置运行数据存储路径
config.setCrawlStorageFolder(rootFolder);
// 下载二进制数据(图片是二进制的数据)
config.setIncludeBinaryContentInCrawling(true);
// 需要爬的网站
String[] crawlDomains = {"http://uci.edu/"};
// PageFetcher是用于下载数据的
PageFetcher pageFetcher = new PageFetcher(config);
// 用于控制是否遵守robots协议
RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);
CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer);
// 添加爬虫最初爬取的网页
for (String domain : crawlDomains) {
controller.addSeed(domain);
}
ImageCrawler.configure(crawlDomains, storageFolder);
// 启动爬虫,使用并行
controller.start(ImageCrawler.class, numberOfCrawlers);
}
}
#Tip:本文所用代码是Crawler4j官方代码,只是稍作注解而已