java1234开源博客系统
博客信息

crawler4j多线程爬虫实例

发布时间:『 2016-06-07 09:51』  博客类别:java爬虫技术  阅读(10638) 评论(1)


这个例子演示了如何同时运行两个不同的爬虫。


首先写一个BasicCrawler类:

package com.java1234.multipleCrawlers;


import java.util.Set;
import java.util.regex.Pattern;


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 String[] myCrawlDomains; // 目标爬虫域名

  /**
   * 爬虫实例启动前调用,一般是作用是初始化一些数据
   */
  @Override
  public void onStart() {
    myCrawlDomains = (String[]) myController.getCustomData(); // 获取自定义数据 目标爬虫域名  控制器类对象里会设置的
  }

  /**
   * 这个方法主要是决定哪些url我们需要抓取,返回true表示是我们需要的,返回false表示不是我们需要的Url
   * 第一个参数referringPage封装了当前爬取的页面信息
   * 第二个参数url封装了当前爬取的页面url信息
   */
  @Override
  public boolean shouldVisit(Page referringPage, WebURL url) {
    String href = url.getURL().toLowerCase(); // 得到小写的url
    
    // 正则匹配,过掉一些指定后缀的文件
    if (FILTERS.matcher(href).matches()) {
      return false;
    }

    // 遍历目标域名 指定目标爬虫域名
    for (String crawlDomain : myCrawlDomains) {
      if (href.startsWith(crawlDomain)) {
        return true;
      }
    }

    return false;
  }

  /**
   * 当我们爬到我们需要的页面,这个方法会被调用,我们可以尽情的处理这个页面
   * 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("======================");
  }
}


再定义一个爬虫控制器MultipleCrawlerController类:

package com.java1234.multipleCrawlers;



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 MultipleCrawlerController {
 
  public static void main(String[] args) throws Exception {
  
    String crawlStorageFolder = "c:/crawl"; // 定义爬虫数据存储位置

    CrawlConfig config1 = new CrawlConfig(); // 爬虫配置实例1
    CrawlConfig config2 = new CrawlConfig(); // 爬虫配置实例2

    // 两个爬虫实例文件分别存储各种文件夹
    config1.setCrawlStorageFolder(crawlStorageFolder + "/crawler1");
    config2.setCrawlStorageFolder(crawlStorageFolder + "/crawler2");

    config1.setPolitenessDelay(1000); // 设置1秒爬取一次
    config2.setPolitenessDelay(2000); // 设置2秒爬取一次

    config1.setMaxPagesToFetch(5); // 设置最大爬取页数5
    config2.setMaxPagesToFetch(6); // 设置最大爬取页数6

    // 使用两个PageFetcher实例
    PageFetcher pageFetcher1 = new PageFetcher(config1);
    PageFetcher pageFetcher2 = new PageFetcher(config2);

    // 使用同一个RobotstxtServer实例
    RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
    RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher1);

    CrawlController controller1 = new CrawlController(config1, pageFetcher1, robotstxtServer);
    CrawlController controller2 = new CrawlController(config2, pageFetcher2, robotstxtServer);

    // 分别指定目标爬虫域名
    String[] crawler1Domains = {"http://www.zuidaima.com/"}; 
    String[] crawler2Domains = {"http://www.java1234.com/"}; 

    // 设置自定义数据
    controller1.setCustomData(crawler1Domains); 
    controller2.setCustomData(crawler2Domains);

    // 配置爬虫种子页面,就是规定的从哪里开始爬,可以配置多个种子页面
    controller1.addSeed("http://www.zuidaima.com/");
    controller1.addSeed("http://www.zuidaima.com/share/p1-s1.htm");

    controller2.addSeed("http://www.java1234.com/");
    controller2.addSeed("http://www.java1234.com/a/bysj/javaweb/");

    // 启动爬虫,爬虫从此刻开始执行爬虫任务,根据以上配置  根据源码  这种启动是无阻塞的
    controller1.startNonBlocking(BasicCrawler.class, 5);
    controller2.startNonBlocking(BasicCrawler.class, 7);

    controller1.waitUntilFinish(); // 直到完成
    System.out.println("爬虫1任务结束");

    controller2.waitUntilFinish();  // 直到完成
    System.out.println("爬虫2任务结束");
  }
}


运行结果:

docId:1
url:http://www.java1234.com/
上级页面docId:0
纯文本长度: 3852
html长度: 45322
输出链接个数: 148
======================
docId:1
url:http://www.zuidaima.com/
上级页面docId:0
纯文本长度: 5068
html长度: 57570
输出链接个数: 325
======================
docId:2
url:http://www.zuidaima.com/share/p1-s1.htm
上级页面docId:0
纯文本长度: 5272
html长度: 66409
输出链接个数: 261
======================
docId:3
url:http://www.zuidaima.com/share/2814499085634560.htm
上级页面docId:1
纯文本长度: 3576
html长度: 34466
输出链接个数: 218
======================
docId:3
url:http://www.java1234.com/a/bysj/javaweb/2014/0401/1896.html
上级页面docId:1
纯文本长度: 2133
html长度: 29038
输出链接个数: 55
======================
docId:4
url:http://www.zuidaima.com/share/2519215530527744.htm
上级页面docId:1
纯文本长度: 4816
html长度: 38285
输出链接个数: 228
======================
docId:5
url:http://www.zuidaima.com/share/2783070349888512.htm
上级页面docId:1
纯文本长度: 3985
html长度: 34784
输出链接个数: 225
======================
docId:4
url:http://www.java1234.com/a/bysj/javaweb/2016/0316/5826.html
上级页面docId:1
纯文本长度: 2119
html长度: 30022
输出链接个数: 53
======================
docId:5
url:http://www.java1234.com/a/javaziliao/shuji/2016/0603/6204.html
上级页面docId:1
纯文本长度: 2040
html长度: 26507
输出链接个数: 56
======================
爬虫1任务结束
爬虫2任务结束


完整代码:http://pan.baidu.com/s/1eS8s3zc

关键字:   crawler4j     爬虫  
关注Java1234微信公众号
博主信息
Java1234_小锋
(知识改变命运,技术改变世界)
Powered by Java1234 V3.0 Copyright © 2012-2016 Java知识分享网 版权所有