GuozhongCrawler實現一個完整爬蟲

    通過上一節開發環境搭建中的百度新聞的爬蟲例子,相信你們已經對GuozhongCrawler簡潔的API產生濃厚興趣了。不過這個還不算一個入門例子。只是完成了簡單的下載和解析。如今咱們來完成一個比較完整的爬蟲吧。html

    爲了體現GuozhongCrawler適應業務靈活性。咱們以抓取西刺代理(http://www.xici.net.co/nn/1)的代理IP爲需求。須要遍歷每一頁全部的IP並抓取下來,直到抓完全部的IP爲止。java

    網頁以下:數據庫

    

    一、新建一個Java項目命名爲XiciCrawler而且添加依賴項目爲GuozhongCrawler或者直接加入GuozhongCrawler.jar爲依賴庫。若是你們不知道怎麼建依賴項目請看個人GuozhongCrawler開發環境搭建ide

    

    二、新建一個爬蟲入口Class名爲StartCrawXici.java。包名自行擬定。這裏命名爲guozhong.crawler.impl。選中public static void main(String[]args)生成main方法。StartCrawXici.java代碼以下編碼



public class StartCrawXici {

    /**
     * @param args
     */
    public static void main(String[] args) {
        CrawlTask task = new CrawlTask("西刺抓代理IP");//給任務取個名字
        CrawlManager.prepareCrawlTask(task)
        .withThread(5)//設置下載線程數5.  默認值是5
        .withStartUrl("http://www.xici.net.co/nn/1", "utf-8")//設置入口URL 並設置頁面編碼
        .addPageProccess(new ParseProxyIpPage())//抓取過程當中的頁面解析器
        .withPipeline(new XiciPipeLine())//離線管道
        .start();//啓動
    }

}


url

三、ParseProxyIpPage.java是處理頁面的實現類。須要實現一個PageProcessor Interface。PageProcessor接口設計以下:.net

/**
 * 網頁處理接口
 * @author Administrator
 *
 */
public interface PageProcessor {
    /**
     * 標記這個PageProcessor,應該處理哪一種Request請求的頁面   初始URL能夠返回null
     * @return
     */
    public String getTag();
    
    /**
     * 若是須要頁面動態交互JS,定義一個PageScript返回
     * @return
     */
    public PageScript getJavaScript();
    
    /**
     * 當啓動代理Ip訪問時須要重寫此方法,返回正常網頁應該帶有的字符串標識。好比www.baidu.com帶有「百度」
     * @return
     */
    public Pattern getNormalContain();
    
    /**
     * 處理一個頁面
     * @param page
     * @param context
     * @return
     */
    public void process(OkPage page,StartContext context,List<Proccessable> result)throws Exception;
    
    /**
     * 處理錯誤頁面
     * @param page
     * @param context
     */
    public void proccessErrorPage(Page page,StartContext context)throws Exception;
}
線程


由於這裏是處理入口URL頁面。且不須要使用到JS和代理IP。因此getTag()getJavaScript()和getNormalContain()都不須要實現。本節重點解釋process()方法如何使用。至於proccessErrorPage()方法實現和process大同小異。無非是處理錯誤的內容的html罷了。process()實現以下設計

    @Override
    public void process(OkPage page, StartContext context,
            List<Proccessable> result) throws Exception {
        System.out.println("該頁面的URL:"+page.getRequest().getUrl());
        Document doc = Jsoup.parse(page.getContent());
        Pattern pattern = Pattern.//抽取代理IP的正則
                compile("([\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3})\\s*(\\d+)\\s*([^\\s]+)\\s*([^\\s]+)\\s*([^\\s]+)");
        Matcher matcher = pattern.matcher(doc.text());
        XiciProxy proxy = null;
        while(matcher.find()){
            proxy = new XiciProxy();
            proxy.setIp(matcher.group(1));
            proxy.setPort(matcher.group(2));
            proxy.setPosition(matcher.group(3));
            proxy.setAnonymity("高匿".equals(matcher.group(4)));
            proxy.setType(matcher.group(5));
            result.add(proxy);//加入到界面處理結果的集合中
        }
        
        //判斷有沒有下一頁的URL。有則取得下一頁的URL
        Element next_a = doc.select("a[class=next_page]").first();
        if(next_a != null){
            String next_url = next_a.attr("href");
            Request req = context.createRequest(next_url, null, 0, "utf-8");//第二個參數傳Tag由於這裏一直是用初始頁面處理器也就是ParseProxyIpPage自己。因此能夠傳null
            //第三個參數是設置request的優先級只有使用PriorityRequestQueue或者DelayedPriorityRequestQueue纔有效
            result.add(req);//添加到跟進URL隊列
        }
    }
代理

4XiciPipeLine是實現離線存儲的管道類。須要實現一個PipeLine Interface。PipeLine接口設計以下:

public interface  Pipeline extends Serializable{
    
    /**
     * 全部的結構化數據將流向這裏。在這裏存儲你的bean
     * @param procdata
     */
    public  void proccessData(List<Proccessable> procdata);
}

XiciPipeLine.java實現以下;

public class XiciPipeLine implements Pipeline {

    @Override
    public void proccessData(List<Proccessable> arg0) {
        if(ProccessableUtil.instanceOfClass(arg0, XiciProxy.class)){//判斷集合類型是不是XiciProxy
            List<XiciProxy> list = ProccessableUtil.convert(arg0, XiciProxy.class);//轉換
            for (XiciProxy proxy : list) {
                //在這裏存儲到你想要的任何數據庫
                System.out.println("save:"+proxy);
            }
        }
    }

}

至此完成了一個花刺代理的爬蟲。如今把項目圖貼出來給你們看看吧


是的4個類完成一個爬蟲。屌不屌!

在這裏補充XiciProxy.java實體類的代碼

public class XiciProxy implements Proccessable{
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private String ip;
    
    private String port;
    
    private String position;
    
    private boolean isAnonymity;
    
    private String type;

//後面getter setter忽略...

}

注:全部實體類都要實現Proccessable接口。只是爲了標記做用。讓引擎能夠統一處理。無其餘做用

相關文章
相關標籤/搜索