java爬虫框架Webcontroller

git地址:https://github.com/CrawlScript/WebCollector

业务需要爬取一个网站所有手机信息 ,最开始用了crawler4j这个框架,挺简单的,但是发现不能满足我的需求;只支持单页面信息抓取,但是我是要多页面抓取;需要在一级页面抓取到所有的二级页面的链接,再加入所有二级页面的链接,进行抓取所有三级页面的信息;后来改成了webcontroller,发现可以实现我的需求:

爬虫原理就是抓取到页面(page)的所有信息,输出为一个html,然后用jsoup去解析这个html,根据id、class等定位到对应的页面元素,然后进行取值。

注意事项:这个框架有个回滚机制,如果在添加一条数据的时候,里面有一个地方报异常的,这一整条数据都不会添加,所以为了数据全量,一定要先把控制台输出的代码异常全部解决!

一般情况是 Elements 为空缺去取数据导致报异常,一般是判断  elements != null && elements .size()>0

上代码:(www.***.cn改成自己要抓取的网址

import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.ArrayList;
import java.util.List;

/**
 * Crawling news from github news
 *
 * @author hu
 */
public class DemoAutoNewsCrawler extends BreadthCrawler {

    static int grade = 1;//爬虫的深度,第一次为1

    static List list = new ArrayList();//url种子

    /**
     * @param crawlPath crawlPath is the path of the directory which maintains
     *                  information of this crawler
     * @param autoParse if autoParse is true,BreadthCrawler will auto extract
     *                  links which match regex rules from pag
     */
    public DemoAutoNewsCrawler(String crawlPath, boolean autoParse) {
        super(crawlPath, autoParse);
        /*start pages*/
        this.addSeed("http://www.***.cn/cell_phone_index/subcate57_list_1.html");
        //循环添加所有链接
//        for(int pageIndex = 1; pageIndex <= 1; pageIndex++) {
//            String seedUrl = String.format("https://list.jd.com/list.html?cat=9987,653,655&page=1&sort=sort_rank_asc&trans=1&JL=6_0_0#J_main", pageIndex);
//            this.addSeed(seedUrl);
//        }
        setThreads(1);
        getConf().setTopN(100);
        
    }

    public void visit(Page page, CrawlDatums next) {
        String url = page.url();
        /*if page is news page*/
        if (page.matchUrl("http://www.***.cn/.*")) { // .*代表后面匹配所有
           Document doc =  page.doc();
           //爬虫的深度为1
           if(grade == 1){
               Element element = doc.getElementById("J_PicMode");
               Elements elements = element.getAllElements();
               for (Element el: elements) {
                   Elements e = el.getElementsByClass("pic");
                   for (Element e1: e) {
                       String s = el.children().attr("href");
                       if(s != null && !"".equals(s)){
                           list.add(el.children().attr("href"));//加入第二级链接
                       }
                       System.out.println(el.children().attr("href"));
                   }
               }
           }
           //爬虫的深度为2
           else if(grade == 2){
               Elements e = doc.getElementsByClass("_j_MP_more section-more");
               for (Element e1: e) {
                   String s = e.attr("href");
                   if(s != null && !"".equals(s)){
                       list.add(e.attr("href"));//加入第三级链接
                   }
               }
           }else if(grade == 3){
               Elements e1 = doc.getElementsByClass("product-model__name");
               for (Element e: e1) {
                   System.out.println("手机型号:" + e1.text());
               }
               if (doc.select("#newPmVal_0") != null) {
                   System.out.println("上市日期:" + doc.select("#newPmVal_0").get(0).text());
               }
           }
        }
    }

    public static void main(String[] args) throws Exception {
        DemoAutoNewsCrawler crawler = new DemoAutoNewsCrawler("crawl", true);
        /*start crawl with depth of 4*/
        crawler.start(4);
        System.out.println("爬虫深度:" + grade);
        System.out.println("种子大小:"+list.size());
        System.out.println("第一次执行完毕===============================");
        //提升深度
        grade++;
        for(int pageIndex = 1; pageIndex <= 2; pageIndex++) {
            System.out.println("加入的子链接:" + list.get(pageIndex-1));
            String seedUrl = String.format("http://www.***.cn"+list.get(pageIndex-1), pageIndex);
            crawler.addSeed(seedUrl);
        }
        //子链接加入完毕之后清空list
        list.clear();
        //第二次执行
        crawler.start(4);
        System.out.println("爬虫深度:" + grade);
        System.out.println("种子大小:"+list.size());
        System.out.println("第二次执行完毕===============================");
        //提升深度
        grade++;
        for(int pageIndex = 1; pageIndex <= 2; pageIndex++) {
            System.out.println("加入的子链接:" + list.get(pageIndex-1));
            String seedUrl = String.format("http://www.***.cn"+list.get(pageIndex-1), pageIndex);
            crawler.addSeed(seedUrl);
        }
        //第三次执行
        crawler.start(4);
        System.out.println("爬虫深度:" + grade);
        System.out.println("种子大小:"+list.size());
        System.out.println("第三次执行完毕===============================");
    }

}

使用的maven,pom.xml依赖:


    
        cn.edu.hfut.dmic.webcollector
        WebCollector
        2.73-alpha
    

    
        org.jsoup  
        jsoup
        1.11.3
    

注意事项:

页面上有些元素是 class中间是用空格隔开的,如果我们要取它们,则需要:

doc.select(".a.b") 或者doc.select(".a .b")中间也用空格,才能取到!

你可能感兴趣的:(java爬虫框架Webcontroller)