1. 程式人生 > >Crawler4j 快速入門

Crawler4j 快速入門

crawler4j是Java實現的開源網路爬蟲。提供了簡單易用的介面,可以在幾分鐘內建立一個多執行緒網路爬蟲

crawler4j中用了slf4j來記錄專案執行日誌資訊。我們使用slf4j具體實現類log4j

建立一個maven專案。在pom.xml貼上所需jar

    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.8.2</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.25</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>edu.uci.ics</groupId>
      <artifactId>crawler4j</artifactId>
      <version>4.2</version>
    </dependency>

在resources下貼上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 ]

編寫爬蟲類

package com.gcx.crawler;

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;

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

/**
 * 自定義爬蟲類myCrawler需要繼承WebCrawler,決定哪些url被爬取以及處理爬的頁面資訊
 */
public class MyCrawler extends WebCrawler {

    /**
     * 正則匹配指定的字尾檔案
     */
    private final static Pattern FILTERS= Pattern.compile(".*(\\.(css|js|gif|jpg|png|mp3|zip|gz))$");


    /**
     *   根據url進行網頁的解析,對返回為TRUE的網頁進行抓取
     *   第一個引數referringPage封裝了當前爬取的頁面資訊
     *   第二個引數封裝了當前爬取頁面的url資訊
     */
    @Override
    public boolean shouldVisit(Page referringPage, WebURL url) {
        //小寫url
        String href=url.getURL().toLowerCase();
        //正則匹配,過濾掉我們不需要的字尾檔案
        return !FILTERS.matcher(href).matches()//匹配過濾掉不需要的字尾檔案
                && href.startsWith("http://www.bjsxt.com");//url必須是http://www.baidu.com開頭
    }

    /**
     * 解析網頁內容,page類包含了豐富的方法,可以利用這些方法得到網頁的內容和屬性
     * 當我們爬取到我們需要的頁面,這個方法會被呼叫,我們可以隨意處理頁面
     * page 封裝了所有頁面資訊
     *
     */
    @Override
    public void visit(Page page) {
        //獲取url
        String url=page.getWebURL().getURL();
        System.out.println("url:"+url);
        //判斷是否是html資料
        if(page.getParseData() instanceof HtmlParseData){
            //強制型別轉換,獲取html資料物件
            HtmlParseData htmlParseData= (HtmlParseData) page.getParseData();
            //獲得頁面純文字
            String text=htmlParseData.getText();
            //獲得頁面html
            String html=htmlParseData.getHtml();
            //獲取頁面輸出連結
            Set<WebURL> links=htmlParseData.getOutgoingUrls();

            System.out.println("純文字長度: " + text.length());
            System.out.println("html長度: " + html.length());
            System.out.println("輸出連結個數: " + links.size());
        }
    }
}



一個控制器呼叫,我們爬取一個www.bjsxt.com

package com.gcx.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;

/**
 * 爬蟲控制器
 */
public class Controller {
    public static void main(String[] args) throws Exception {
        //定義爬蟲儲存的位置
        String crawStorageFoler="d:/crawler";
        //定義爬蟲執行緒7個
        int numberOfCrawlers=1;
        //定義爬蟲配置
        CrawlConfig config=new CrawlConfig();
        //設定爬蟲檔案儲存位置
        config.setCrawlStorageFolder(crawStorageFoler);
        //例項化頁面獲取器
        PageFetcher pageFetcher=new PageFetcher(config);
        //例項化爬蟲機器人配置,比如可以設定user-agent
        RobotstxtConfig robotstxtconfig=new RobotstxtConfig();
        //例項化爬蟲機器人對目標伺服器的配置,每個網站都有一個robots.txt檔案
        //規定了該網站哪些頁面可以爬,哪些頁面禁止爬,該類是對robots.txt規範的實現
        RobotstxtServer robotstxtServer=new RobotstxtServer(robotstxtconfig,pageFetcher);
        //例項化爬蟲控制器
        CrawlController controller=new CrawlController(config,pageFetcher,robotstxtServer);
        //配置爬取種子頁面,就是規定從哪裡開始爬,可以配置多個種子頁面
        controller.addSeed("http://www.bjsxt.com");


        //啟動爬蟲,爬蟲從此刻開始執行爬蟲任務
        controller.start(MyCrawler.class,numberOfCrawlers);
    }
}

爬取如下:

簡單一個爬蟲例項搞定

當然還提供了基本的例項

package com.gcx.crawler;

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;
import org.apache.http.Header;

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

/**
 * 自定義爬蟲類myCrawler需要繼承WebCrawler,決定哪些url被爬取以及處理爬的頁面資訊
 */
public class MyCrawler extends WebCrawler {

    /**
     * 正則匹配指定的字尾檔案  指定圖片字尾
     */
    private static final Pattern IMAGE_EXTENSIONS = Pattern.compile(".*\\.(bmp|gif|jpg|png)$");

    /**
     * 這個方法主要是決定哪些url我們需要抓取,返回true表示是我們需要的,返回false表示不是我們需要的Url
     * 第一個引數referringPage封裝了當前爬取的頁面資訊
     * 第二個引數url封裝了當前爬取的頁面url資訊
     */
    @Override
    public boolean shouldVisit(Page referringPage, WebURL url) {
        String href = url.getURL().toLowerCase(); // 得到小寫的url
        // 過濾掉含有圖片字尾的url
        if (IMAGE_EXTENSIONS.matcher(href).matches()) {
            return false;
        }

        // 只接受www.bjsxt.com開頭的url
        return href.startsWith("http://www.bjsxt.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());
            }
        }

    }
}



package com.gcx.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;

/**
 * 爬蟲控制器
 */
public class Controller {
    public static void main(String[] args) throws Exception {
        String crawlStorageFolder = "d:/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.bjsxt.com/");

        /*
         * 啟動爬蟲,爬蟲從此刻開始執行爬蟲任務,根據以上配置
         */
        controller.start(MyCrawler.class, numberOfCrawlers);
    }
}

執行如下: