GuozhongCrawler看准网爬虫动态切换IP漫爬虫

Stella981
• 阅读 778

有些关于URL去重的方面代码没有提供,需要自己去实现。主要这里提供思路

项目地址:http://git.oschina.net/woshidaniu/GuozhongCrawler/tree/master/example/changeProxyIp/

首先爬虫入口类:

public class PervadeSpider {

    public static void main(String[] args) {
        CrawTaskBuilder builder = CrawlManager.getInstance()
        .prepareCrawlTask("看准网漫爬虫", DefaultPageDownloader.class)
        .useThread(200)// 使用多个线程下载
        .useDynamicEntrance(DynamicEntranceImpl.class)
        .useProxyIpPool(KanzhunProxyIpPool.class, 800, 1000 * 60 * 20, 30)
        .useQueueSimpleBlockingRequest()//采用广度优先策略,当然redis队列也是fifo。如果想做分布式爬虫的话可以设置redis队列
        .usePageEncoding(PageEncoding.UTF8);
        CrawlTask spider = builder.build();
        CrawlManager.getInstance().start(spider);
    }
    
    public static final class DynamicEntranceImpl extends DynamicEntrance{

        @Override
        public List loadStartContext() {
            StartContext context = new StartContext();
            context.injectSeed(context.createPageRequest("http://www.kanzhun.com/companyl/search/?ka=banner-com", ExtractUrlPageProcessor.class));//公司
            context.injectSeed(context.createPageRequest("http://www.kanzhun.com/salaryl/search/?stype=&ka=banner-salary", ExtractUrlPageProcessor.class));//工资
            context.injectSeed(context.createPageRequest("http://www.kanzhun.com/jobl/p/?ka=banner-recruit", ExtractUrlPageProcessor.class));//招聘
            context.injectSeed(context.createPageRequest("http://www.kanzhun.com/interviewl/search/?stype=&ka=banner-interview", ExtractUrlPageProcessor.class));//面试
            context.injectSeed(context.createPageRequest("http://www.kanzhun.com/topic/100.html?ka=com-topic-1", ExtractUrlPageProcessor.class));//公司之最
            return Arrays.asList(context);
        }
        
    }
}

动态代理IP提供类:

public class KanzhunProxyIpPool extends ProxyIpPool {
    public static final String IP_RESOURCE = "地址忽略";//地址请求的个数必须设置为initProxyIp(int size)中size的个数
    public KanzhunProxyIpPool(int initSize, long pastTime, int max_use_count) {
        super(initSize, pastTime, max_use_count);
    }

    private Pattern extractIp = Pattern.compile("([\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}):(\\d+)");
    
    @Override
    protected List initProxyIp(int size) throws Exception {
        List   ip = new ArrayList();
        URL url = null;
        BufferedReader br = null;
        StringBuffer buf = new StringBuffer();
        try {
            url = new URL(IP_RESOURCE);
            InputStream in = url.openStream();
            br = new BufferedReader(new InputStreamReader(in,"utf-8"));
            String temp = null;
            
            while((temp = br.readLine())!=null){
                buf.append(temp).append("\n");
            }
            
            ProxyIp proxy = null;
            Matcher matcher = extractIp.matcher(buf);
            while(matcher.find()){
                proxy = new ProxyIp(matcher.group(1), Integer.parseInt(matcher.group(2)));
                ip.add(proxy);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(buf);
        }finally{
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return ip;
    }

}

漫爬页面处理类:

public class ExtractUrlPageProcessor implements PageProcessor {
    
    
    
    private String domain = "http://www.kanzhun.com";
    
    private List urlFilters = new ArrayList();
    
    private List urlRegulars = null;
    
    public ExtractUrlPageProcessor(){
        System.out.println("加载漫爬抽取URL正则");
        urlRegulars = ConfigReader.getExtractRegular();
        System.out.println("加载漫爬规则完毕");
        addURLFilter(new URLFilter() {
            
            @Override
            public boolean filter(String url) {
                return !url.contains("javascript");//去除jquery标签
            }
        });
        addURLFilter(new URLFilter() {
            
            @Override
            public boolean filter(String url) {
                return url.contains("http://www.kanzhun.com");//保证域名内URL
            }
        });
        addURLFilter(new URLFilter() {
            
            @Override
            public boolean filter(String url) {
                for (Pattern pattern : urlRegulars) {
                     boolean result = pattern.matcher(url).find();
                     if(result)
                         return true;
                }
                return false;//保证url符合urlRegulars里任意一个正则
            }
        });
        
    }
    
    /**
     * kanzhunId抽取正则
     */
    final static Pattern[] idExtracts = new Pattern[]{
        Pattern.compile("gso(\\d+)[^\\d]+"),//简介抽取公司id
        Pattern.compile("gsr(\\d+)[^\\d]+"),//点评抽取公司id
        Pattern.compile("gsm(\\d+)[^\\d]+"),//面试抽取公司id
        Pattern.compile("gsx(\\d+)[^\\d]+"),//工资抽取公司id
        Pattern.compile("g(\\d+)[^\\d]+"),//招聘抽取公司id
        Pattern.compile("gsp(\\d+)[^\\d]+"),//照片抽取公司id
        Pattern.compile("gsl(\\d+)[^\\d]+")//员工抽取公司id
    };

    @Override
    public PageScript getJavaScript() {
        // TODO Auto-generated method stub
        return null;
    }
    
    
    private Pattern normalContain = Pattern.compile("看准网");

    @Override
    public Pattern getNormalContain() {
        return normalContain;
    }

    @Override
    public void process(OkPage page,StartContext context,List queue,List objectContainer) throws Exception {
        // TODO Auto-generated method stub
        /**
         * 每个页面抽取的符合urlRegulars规则的url
         */
        Set extractUrls = new HashSet();
        
        /**
         * 每个页面所有的kanzhunId
         * 这里解释下比如阿里巴巴的首页是http://www.kanzhun.com/gso9012.html?ka=com1-title
         * 那个阿里巴巴的kanzhunId就是9012
         * 我们可以根据这个推导出阿里巴巴的
         * 点评页:http://www.kanzhun.com/gsr9012.html?ka=com-blocker1-review
         * 面试页:http://www.kanzhun.com/gsm9012.html?ka=com-blocker1-interview
         * 工资页:http://www.kanzhun.com/gsx9012.html?ka=com-blocker1-salary
         * 招聘页:http://www.kanzhun.com/job/g9012.html?ka=com-blocker1-job
         * 照片页:http://www.kanzhun.com/gsp9012.html?ka=com-blocker1-photo
         * 员工页:http://www.kanzhun.com/gsl9012.html?ka=com-blocker1-employee
         *
         */
        Set kanzhunIds = new HashSet();
        
        Document doc = Jsoup.parse(page.getContent());
        Elements allLinks = doc.select("a");
        String href = null;
        for (Element link : allLinks) {
            href = link.attr("href");
            if(href.startsWith("/")){
                href = domain+href;
            }
            if(pass(href)){
                extractUrls.add(href);
            }
            //抽取页面所有包含的kanzhunID
            for (Pattern pattern : idExtracts) {
                Matcher matcher = pattern.matcher(href);
                if(matcher.find()){
                    kanzhunIds.add(matcher.group(1));
                }
            }
        }
        
        //step1
        System.out.println(page.getRequest().getUrl()+"抽取了URL"+extractUrls.size()+"个:");
        //对url去重(这个需要你们自己实现这里用伪代码表示)
        System.out.println("去出重复url...");
        
        //step2
        System.out.println(page.getRequest().getUrl()+"抽取了kanzhunId"+kanzhunIds.size()+"个:");
        //对抓过的kanzhunId进行去重(这个需要你们自己实现这里用伪代码表示)
        System.out.println("kanzhunId进行去重...");
        
        
        //将抽取的URL加入到队列
        for (String extractUrl:extractUrls) {
            PageRequest pageRequest = context.createPageRequest(extractUrl, ExtractUrlPageProcessor.class);
            queue.add(pageRequest);//加到队列
        }
        
        //将抽取的kanzhunId封装成每个企业的主页URL。抓取企业信息
        for (String kanzhunId:kanzhunIds) {
            PageRequest pageRequest = context.createPageRequest("http://www.kanzhun.com/gso"+kanzhunId+".html?ka=com1-title", CompanyPageProcessor.class);
            queue.add(pageRequest);//加到队列
        }
        
    }
    
    @Override
    public void processErrorPage(Page arg0, StartContext arg1) throws Exception {
        // TODO Auto-generated method stub
        
    }
    
    /**
     * 对每个URL进行filter
     * @param url
     * @return
     */
    private boolean pass(String url){
        for (URLFilter filter : urlFilters) {
            if(!filter.filter(url)){
                return false;
            }
        }
        return true;
    }     

    
    public void addURLFilter(URLFilter urlFilter){
        urlFilters.add(urlFilter);
    }
}

最后URL抽取规则贴上。

   
        
        /pl[act][a-z0-9]+\.html
        
        
        
        /xs[ac][a-z0-9]+\.html
        
        
        
        /jobli_.+
        
        
        /ms[ac].+
        
        
        /topic/[a-z0-9]+
        
        
        
        /salary/(\d+)/
        /interview/(\d+)/
    

搞定。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
3年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java爬虫之JSoup使用教程
title:Java爬虫之JSoup使用教程date:201812248:00:000800update:201812248:00:000800author:mecover:https://imgblog.csdnimg.cn/20181224144920712(https://www.oschin
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这