该实例演示如何通过调用接口实现停止爬虫线程;
首先建一个BasicCrawler类:
package com.java1234.shutdownCrawler; import java.util.Set; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import edu.uci.ics.crawler4j.crawler.Page; import edu.uci.ics.crawler4j.crawler.WebCrawler; import edu.uci.ics.crawler4j.parser.HtmlParseData; import edu.uci.ics.crawler4j.url.WebURL; /** * 自定义爬虫类需要继承WebCrawler类,决定哪些url可以被爬以及处理爬取的页面信息 * @author user * */ public class BasicCrawler extends WebCrawler { // 正则匹配指定的后缀文件 private static final Pattern FILTERS = Pattern.compile( ".*(\\.(css|js|bmp|gif|jpe?g|png|tiff?|mid|mp2|mp3|mp4|wav|avi|mov|mpeg|ram|m4v|pdf" + "|rm|smil|wmv|swf|wma|zip|rar|gz))$"); private static final String DOMAIN = "http://www.java1234.com/"; /** * 这个方法主要是决定哪些url我们需要抓取,返回true表示是我们需要的,返回false表示不是我们需要的Url * 第一个参数referringPage封装了当前爬取的页面信息 * 第二个参数url封装了当前爬取的页面url信息 */ @Override public boolean shouldVisit(Page referringPage, WebURL url) { String href = url.getURL().toLowerCase(); // 转换成小写 return !FILTERS.matcher(href).matches() && href.startsWith(DOMAIN); // 正则匹配指定域名 } /** * 当我们爬到我们需要的页面,这个方法会被调用,我们可以尽情的处理这个页面 * page参数封装了所有页面信息 */ @Override public void visit(Page page) { int docid = page.getWebURL().getDocid(); // 获取docid url的唯一识别 类似主键 String url = page.getWebURL().getURL(); // 获取url int parentDocid = page.getWebURL().getParentDocid(); // 获取上级页面的docId System.out.println("docId:"+docid); System.out.println("url:"+url); System.out.println("上级页面docId:"+parentDocid); if (page.getParseData() instanceof HtmlParseData) { // 判断是否是html数据 HtmlParseData htmlParseData = (HtmlParseData) page.getParseData(); // 强制类型转换,获取html数据对象 String text = htmlParseData.getText(); // 获取页面纯文本(无html标签) String html = htmlParseData.getHtml(); // 获取页面Html Set<WebURL> links = htmlParseData.getOutgoingUrls(); // 获取页面输出链接 System.out.println("纯文本长度: " + text.length()); System.out.println("html长度: " + html.length()); System.out.println("输出链接个数: " + links.size()); } System.out.println("======================"); } }
再建一个ControllerWithShutdown类:
package com.java1234.shutdownCrawler; import edu.uci.ics.crawler4j.crawler.CrawlConfig; import edu.uci.ics.crawler4j.crawler.CrawlController; import edu.uci.ics.crawler4j.fetcher.PageFetcher; import edu.uci.ics.crawler4j.robotstxt.RobotstxtConfig; import edu.uci.ics.crawler4j.robotstxt.RobotstxtServer; /** * 爬虫控制器 * @author user * */ public class ControllerWithShutdown { public static void main(String[] args) throws Exception { String crawlStorageFolder = "c:/crawl"; // 定义爬虫数据存储位置 int numberOfCrawlers =2; // 定义2个爬虫,也就是2个线程 CrawlConfig config = new CrawlConfig(); // 实例化爬虫配置 config.setCrawlStorageFolder(crawlStorageFolder); // 设置爬虫文件存储位置 config.setPolitenessDelay(1000); // 1秒爬一次 config.setMaxPagesToFetch(-1); // 无限爬取 // 实例化爬虫控制器 PageFetcher pageFetcher = new PageFetcher(config); // 实例化页面获取器 RobotstxtConfig robotstxtConfig = new RobotstxtConfig(); // 实例化爬虫机器人配置 比如可以设置 user-agent // 实例化爬虫机器人对目标服务器的配置,每个网站都有一个robots.txt文件 规定了该网站哪些页面可以爬,哪些页面禁止爬,该类是对robots.txt规范的实现 RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher); // 实例化爬虫控制器 CrawlController controller = new CrawlController(config, pageFetcher, robotstxtServer); // 配置爬虫种子页面,就是规定的从哪里开始爬,可以配置多个种子页面 controller.addSeed("http://www.java1234.com/"); controller.addSeed("http://www.java1234.com/a/javaziliao/bishi/"); // 启动爬虫,爬虫从此刻开始执行爬虫任务,根据以上配置 无阻塞 controller.startNonBlocking(BasicCrawler.class, numberOfCrawlers); // 休息5秒 Thread.sleep(10 * 1000); System.out.println("休息10秒"); // 停止爬取 controller.shutdown(); System.out.println("停止爬取"); // 等待结束任务 controller.waitUntilFinish(); } }
我们运行下,运行结果:
docId:1 url:http://www.java1234.com/ 上级页面docId:0 纯文本长度: 3793 html长度: 45151 输出链接个数: 150 ====================== docId:3 url:http://www.java1234.com/a/bysj/javaweb/2014/0401/1896.html 上级页面docId:1 纯文本长度: 2142 html长度: 29240 输出链接个数: 55 ====================== docId:2 url:http://www.java1234.com/a/javaziliao/bishi/ 上级页面docId:0 纯文本长度: 2600 html长度: 24418 输出链接个数: 84 ====================== docId:4 url:http://www.java1234.com/a/bysj/javaweb/2016/0316/5826.html 上级页面docId:1 纯文本长度: 2128 html长度: 30224 输出链接个数: 53 ====================== docId:53 url:http://www.java1234.com/a/javaziliao/ 上级页面docId:1 纯文本长度: 3866 html长度: 36174 输出链接个数: 127 ====================== docId:54 url:http://www.java1234.com/javaxuexiluxiantu.html 上级页面docId:1 纯文本长度: 5770 html长度: 23714 输出链接个数: 73 ====================== 休息10秒 停止爬取
实验表明 确实是可以终止爬虫线程的。
上一篇:crawler4j多线程爬虫实例
下一篇:Unicode汉字编码表