zoukankan      html  css  js  c++  java
  • Crawler4j快速入门实例

    项目是基于maven 结构的。

    首先我们在pom.xml中加入log4j以及log4j驱动类支持;

    <!-- 加入log4j支持 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
     
    <!-- 加入slf4j log4j驱动类 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.21</version>
    </dependency>

    <dependency>
          <groupId>edu.uci.ics</groupId>
    
    
          <artifactId>crawler4j</artifactId>
    
    
          <version>4.2</version>
    
    
     </dependency>
     

    log4j.properties配置如下:

    log4j.rootLogger = debug,D,E
       
     
    ### debug ###
    log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.D.File = c://logs/log.log
    log4j.appender.D.Append = true
    log4j.appender.D.Threshold = DEBUG 
    log4j.appender.D.layout = org.apache.log4j.PatternLayout
    log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
     
    ### error ###
    log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.E.File =c://logs/error.log 
    log4j.appender.E.Append = true
    log4j.appender.E.Threshold = ERROR 
    log4j.appender.E.layout = org.apache.log4j.PatternLayout
    log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]

    然后我们先来定义一个MyCrawler

    package com.demo.crawler;
     
    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 
     *
     */
    public class MyCrawler extends WebCrawler {
     
        /**
         * 正则匹配指定的后缀文件
         */
        private final static Pattern FILTERS = Pattern.compile(".*(\.(css|js|gif|jpg"
                                                               + "|png|mp3|mp3|zip|gz))$");
     
         /**
          * 这个方法主要是决定哪些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.baidu.com/");  // url必须是http://wwwbaidu.com/开头,规定站点
         }
     
         /**
          * 当我们爬到我们需要的页面,这个方法会被调用,我们可以尽情的处理这个页面
          * page参数封装了所有页面信息
          */
         @Override
         public void visit(Page page) {
            int docid = page.getWebURL().getDocid(); // 获取docid url的唯一识别 类似主键
            String url = page.getWebURL().getURL();  // 获取url
            String domain = page.getWebURL().getDomain(); // 获取域名
            String path = page.getWebURL().getPath();  // 获取路径 
            String subDomain = page.getWebURL().getSubDomain(); // 获取子域名
            String parentUrl = page.getWebURL().getParentUrl(); // 获取上级Url
            String anchor = page.getWebURL().getAnchor(); // 获取锚点
     
            System.out.println("docid:"+docid);
            System.out.println("url:"+url);
            System.out.println("domain:"+domain);
            System.out.println("path:"+path);
            System.out.println("subDomain:"+subDomain);
            System.out.println("parentUrl:"+parentUrl);
            System.out.println("anchor:"+anchor);
         
             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());
             }

    Header[] responseHeaders = page.getFetchResponseHeaders(); // 获取响应头消息 if (responseHeaders != null) { System.out.println("响应的头消息"); for (Header header : responseHeaders) { System.out.println(header.getName()+"+"+header.getValue()); } } } }

    再写一个控制器Controller:

    package com.demo.crawler;
     
    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 
     *
     */
    public class Controller {
        public static void main(String[] args) throws Exception {
            String crawlStorageFolder = "c:/crawl"; // 定义爬虫数据存储位置
            int numberOfCrawlers = 7; // 定义7个爬虫,也就是7个线程
     
            CrawlConfig config = new CrawlConfig(); // 定义爬虫配置
            config.setCrawlStorageFolder(crawlStorageFolder); // 设置爬虫文件存储位置
     
         /* * 设置请求的频率 * 每1000毫秒,也就是两次请求的间隔至少是1秒 */ config.setPolitenessDelay(1000); /* * 设置请求的网页的深度(后面专门会讲) 设置2 为两层 * 默认值-1 无限深度 */ config.setMaxDepthOfCrawling(2); /* * 设置爬取的最大网页数 这里设置1000 最多爬取1000次 * 默认值是-1,表示无限制 */ config.setMaxPagesToFetch(1000); /** * 是否爬取二进制文件,比如图片,PDF文档,视频之类的东西 这里设置false 不爬取 * 默认值true,爬取 */ config.setIncludeBinaryContentInCrawling(false); /* * 这里可以设置代理 * config.setProxyHost("proxyserver.example.com"); // 代理地址 * config.setProxyPort(8080); // 代理端口 * * 如果使用代理,也可以设置身份认证 用户名和密码 * config.setProxyUsername(username); config.getProxyPassword(password); */ /* * 这个配置假如设置成true,当一个爬虫突然终止或者奔溃,我们可以恢复; * 默认配置是false;推荐用默认配置,假如设置成true,性能会大打折扣; */ config.setResumableCrawling(false);
    /* * 实例化爬虫控制器 */ 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.baidu.com/"); controller.addSeed("http://www.baidu.com/a/kaiyuan/"); controller.addSeed("http://www.baidu.com/a/bysj/"); /** * 启动爬虫,爬虫从此刻开始执行爬虫任务,根据以上配置 */ controller.start(MyCrawler.class, numberOfCrawlers);

        

    // 休息5秒
    Thread.sleep(10 * 1000);

    System.out.println("休息10秒");

    // 停止爬取
    controller.shutdown();
    System.out.println("停止爬取");

    // 等待结束任务
    controller.waitUntilFinish();

    
    
      
        }
    }

    运行Controller.

    int docid = page.getWebURL().getDocid(); // 获取docid url的唯一识别 类似主键
            String url = page.getWebURL().getURL();  // 获取url
            String domain = page.getWebURL().getDomain(); // 获取域名
            String path = page.getWebURL().getPath();  // 获取路径 
            String subDomain = page.getWebURL().getSubDomain(); // 获取子域名
            String parentUrl = page.getWebURL().getParentUrl(); // 获取上级Url
            String anchor = page.getWebURL().getAnchor(); // 获取锚点
     
            System.out.println("docid:"+docid);
            System.out.println("url:"+url);
            System.out.println("domain:"+domain);
            System.out.println("path:"+path);
            System.out.println("subDomain:"+subDomain);
            System.out.println("parentUrl:"+parentUrl);
            System.out.println("anchor:"+anchor);
  • 相关阅读:
    POJ-图论-最短路模板(邻接矩阵)
    POJ-图论-并查集模板
    POJ-排序-归并排序与逆序对
    【题目自解】北京大学2018计算机学科夏令营上机考试
    【算法总结】图论-拓扑排序
    【算法总结】图论-最短路径
    【算法总结】图论-最小生成树
    【算法总结】图论-并查集
    iOS程序的生命周期
    6款好用的Python IDE
  • 原文地址:https://www.cnblogs.com/iathanasy/p/8109351.html
Copyright © 2011-2022 走看看