• crawler4j多线程爬虫统计分析数据


    该事例演示了如何在多线程中统计和分析数据;

    首先建一个状态实体类CrawlStat:

    package com.demo.collectingData;
     
    /**
     * 爬虫状态实体类 统计爬虫信息
     * @author
     *
     */
    public class CrawlStat {
      private int totalProcessedPages; //处理的页面总数
      private long totalLinks; // 总链接数
      private long totalTextSize; // 总文本长度
     
      public int getTotalProcessedPages() {
        return totalProcessedPages;
      }
     
      public void setTotalProcessedPages(int totalProcessedPages) {
        this.totalProcessedPages = totalProcessedPages;
      }
     
      /**
       * 总处理页面数加1
       */
      public void incProcessedPages() {
        this.totalProcessedPages++;
      }
     
      public long getTotalLinks() {
        return totalLinks;
      }
     
      public void setTotalLinks(long totalLinks) {
        this.totalLinks = totalLinks;
      }
     
      public long getTotalTextSize() {
        return totalTextSize;
      }
     
      public void setTotalTextSize(long totalTextSize) {
        this.totalTextSize = totalTextSize;
      }
     
      /**
       * 总链接数加count个
       * @param count
       */
      public void incTotalLinks(int count) {
        this.totalLinks += count;
      }
     
      /**
       * 总文本长度加total个
       * @param count
       */
      public void incTotalTextSize(int count) {
        this.totalTextSize += count;
      }
    }

    再建一个LocalDataCollectorCrawler类:

    package com.demo.collectingData;
     
    import java.io.UnsupportedEncodingException;
    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;
     
    /**
     * 该类演示了如何在多线程中统计和分析数据
     * @author user
     *
     */
    public class LocalDataCollectorCrawler 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))$");
     
      CrawlStat myCrawlStat; // 定义爬虫状态对象,用户统计和分析
     
      /**
       * 构造方法
       */
      public LocalDataCollectorCrawler() {
        myCrawlStat = new CrawlStat(); // 实例化爬虫状态对象
      }
      
      /**
       * 这个方法主要是决定哪些url我们需要抓取,返回true表示是我们需要的,返回false表示不是我们需要的Url
       * 第一个参数referringPage封装了当前爬取的页面信息
       * 第二个参数url封装了当前爬取的页面url信息
       */
      @Override
      public boolean shouldVisit(Page referringPage, WebURL url) {
        String href = url.getURL().toLowerCase(); // 获取url小写
        return !FILTERS.matcher(href).matches() && href.startsWith("http://www.xxx.com"); // 必须是www.xxx.com域名
      }
     
      /**
       * 当我们爬到我们需要的页面,这个方法会被调用,我们可以尽情的处理这个页面
       * page参数封装了所有页面信息
       */
      @Override
      public void visit(Page page) {
        System.out.println("正在爬取页面:"+page.getWebURL().getURL());
        myCrawlStat.incProcessedPages(); // 处理页面加1
     
        if (page.getParseData() instanceof HtmlParseData) { // 假如是html数据
          HtmlParseData parseData = (HtmlParseData) page.getParseData(); // 获取Html数据
          Set<WebURL> links = parseData.getOutgoingUrls(); // 获取输出链接
          myCrawlStat.incTotalLinks(links.size()); // 总链接加link.size个
          try {
            myCrawlStat.incTotalTextSize(parseData.getText().getBytes("UTF-8").length); // 文本长度增加
          } catch (UnsupportedEncodingException ignored) {
            // Do nothing
          }
        }
        // 每获取3个页面数据 我们处理下数据
        if ((myCrawlStat.getTotalProcessedPages() % 3) == 0) {
          dumpMyData();
        }
      }
     
      /**
       * 获取下爬虫状态
       */
      @Override
      public Object getMyLocalData() {
        return myCrawlStat;
      }
     
      /**
       * 当任务完成时调用
       */
      @Override
      public void onBeforeExit() {
        dumpMyData(); // 处理处理
      }
     
      /**
       * 处理数据
       */
      public void dumpMyData() {
        int id = getMyId();
        System.out.println("当前爬虫实例id:"+id);
        System.out.println("总处理页面:"+myCrawlStat.getTotalProcessedPages());
        System.out.println("总链接长度:"+myCrawlStat.getTotalLinks());
        System.out.println("总文本长度:"+myCrawlStat.getTotalTextSize());
      }
    }

    最后建一个控制器LocalDataCollectorController:

    package com.demo.collectingData;
     
     
    import java.util.List;
     
     
    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 LocalDataCollectorController {
     
      public static void main(String[] args) throws Exception {
        
     
        String rootFolder = "c:/crawl"; // 定义爬虫数据存储位置
        int numberOfCrawlers = 2; // 定义7个爬虫,也就是7个线程
     
        CrawlConfig config = new CrawlConfig(); // 定义爬虫配置
        config.setCrawlStorageFolder(rootFolder); // 设置爬虫文件存储位置
        config.setMaxPagesToFetch(10);  // 设置最大页面获取数
        config.setPolitenessDelay(1000); // 设置爬取策略 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.xxx.com"); // 添加爬虫种子
         
        // 启动爬虫,爬虫从此刻开始执行爬虫任务,根据以上配置
        controller.start(LocalDataCollectorCrawler.class, numberOfCrawlers);
     
        List<Object> crawlersLocalData = controller.getCrawlersLocalData(); // 当多个线程爬虫完成任务时,获取爬虫本地数据
        long totalLinks = 0;
        long totalTextSize = 0;
        int totalProcessedPages = 0;
        for (Object localData : crawlersLocalData) {
          CrawlStat stat = (CrawlStat) localData;
          totalLinks += stat.getTotalLinks();
          totalTextSize += stat.getTotalTextSize();
          totalProcessedPages += stat.getTotalProcessedPages();
        }
     
        // 打印数据
        System.out.println("统计数据:");
        System.out.println("总处理页面:"+totalProcessedPages);
        System.out.println("总链接长度:"+totalLinks);
        System.out.println("总文本长度:"+totalTextSize);
      }
    }

    打印结果:

    正在爬取页面:http://www.xxx.com/
    正在爬取页面:http://www.xxx.com/share/2814499085634560.htm
    正在爬取页面:http://www.xxx.com/share/2519215530527744.htm
    正在爬取页面:http://www.xxx.com/share/2783070349888512.htm
    当前爬虫实例id:2
    总处理页面:3
    总链接长度:672
    总文本长度:22295
    正在爬取页面:http://www.xxx.com/share/2769260213275648.htm
    正在爬取页面:http://www.xxx.com/share/kredis-p1-s1.htm
    正在爬取页面:http://www.xxx.com/share/kswing-p1-s1.htm
    当前爬虫实例id:2
    总处理页面:6
    总链接长度:1299
    总文本长度:46674
    正在爬取页面:http://www.xxx.com/share/kcodehaus-p1-s1.htm
    正在爬取页面:http://www.xxx.com/user/2176279510861824.htm
    正在爬取页面:http://www.xxx.com/blog/2881413902666752.htm
    当前爬虫实例id:2
    总处理页面:9
    总链接长度:1617
    总文本长度:90618
    当前爬虫实例id:1
    总处理页面:1
    总链接长度:326
    总文本长度:10321
    当前爬虫实例id:2
    总处理页面:9
    总链接长度:1617
    总文本长度:90618
    统计数据:
    总处理页面:10
    总链接长度:1943
    总文本长度:100939
    

      

  • 相关阅读:
    典型格雷码-数学规律
    合并两个有序数组
    从fragment跳转到Activity
    fragment如何findviewby
    布局和位置
    preferencefragment
    AndroidStudio导入support-v13
    一些属性作用
    菜单menu
    ActionBar
  • 原文地址:https://www.cnblogs.com/iathanasy/p/8109493.html
Copyright © 2020-2023  润新知