有些关于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<StartContext> 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<ProxyIp> initProxyIp(int size) throws Exception {

        List<ProxyIp>   ip = new ArrayList<ProxyIp>();

        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<URLFilter> urlFilters = new ArrayList<URLFilter>();

    

    private List<Pattern> 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<BasicRequest> queue,List<Proccessable> objectContainer) throws Exception {

        // TODO Auto-generated method stub

        /**

         * 每一个页面抽取的符合urlRegulars规则的url

         */

        Set<String> extractUrls = new HashSet<String>();

        

        /**

         * 每一个页面全部的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<String> kanzhunIds = new HashSet<String>();

        

        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抽取规则贴上。

<ExtractRegular>

        <!-- 行业URL 或者 公司标签  或者 城市-->

        <Regular>/pl[act][a-z0-9]+\.html</Regular>

        

        

        <!-- 行业URL 或者 城市-->

        <Regular>/xs[ac][a-z0-9]+\.html</Regular>

        

        

        <!-- 招聘分类URL-->

        <Regular>/jobli_.+</Regular>

        

        <!-- 面试分类URL-->

        <Regular>/ms[ac].+</Regular>

        

        <!-- 公司之最-->

        <Regular>/topic/[a-z0-9]+</Regular>

        

        

        <!-- 热门职位-->

        <Regular>/salary/(\d+)/</Regular>

        <Regular>/interview/(\d+)/</Regular>

    </ExtractRegular>

搞定。

GuozhongCrawler看准网爬虫动态切换IP漫爬虫的更多相关文章

  1. Python 爬虫使用动态切换ip防止封杀

    对于爬虫被封禁 ! 爬虫一般来说只要你的ip够多,是不容易被封的. 一些中小网站要封杀你,他的技术成本也是很高的,因为大多数网站没有vps,他们用的是虚拟空间或者是sae,bae这样的paas云. 其 ...

  2. (转)内网网站发布到外网-nat123动态公网IP动态域名解析

    环境描述: 路由器分配的是动态公网IP,且有路由器登录管理权限,网站服务器部署在路由器内部网络.如何将内网网站发布到外网大众访问? 解决方案: 内网使用nat123动态域名解析,将域名实时固定解析到路 ...

  3. node.js 爬虫动态代理ip

    参考文章: https://andyliwr.github.io/2017/12/05/nodejs_spider_ip/ https://segmentfault.com/q/10100000081 ...

  4. [转]IP动态切换脚本

    因为公司办公室要设置固定IP才行,而家里的IP段和公司是不一样的,家里采用了DHCP机制,这样每次就得改IP设置,很是不方便,就写了这个脚本来动态切换,很流畅的说!WINXP,WIN7测试通过~嘿嘿~ ...

  5. python爬虫-《笔趣看》网小说《悟空看私聊》

    小编是个爱看小说的人,哈哈 # -*- coding:UTF-8 -*- ''' 类说明:下载<笔趣看>网小说<悟空看私聊> ''' from bs4 import Beaut ...

  6. 简单爬虫,突破IP访问限制和复杂验证码,小总结

    简单爬虫,突破复杂验证码和IP访问限制 文章地址:http://www.cnblogs.com/likeli/p/4730709.html   好吧,看题目就知道我是要写一个爬虫,这个爬虫的目标网站有 ...

  7. 随机切换IP和UA

    在爬虫爬取过程中,网站会根据我们的IP和UA去确认到底是浏览器操作还是爬虫在操作,所以,为了让爬虫不被网站禁止,随机切换Ip 和UA是很重要的,因为这个类在各个爬虫中经常要用到,所以可以自已维护一份随 ...

  8. 动态切换数据库(EF框架)

             文章简略:本文测试项目为Silverlight+EF+RIA Service动态切换数据库的问题 通常,Ado.net EntityFramework的数据库连接字符串Connect ...

  9. ExtJS动态切换主题

    ExtJS动态切换主题         在Sencha Cmd构建的Ext程序中怎么去动态切换主题,目前看好像只能单一切换,但是在官网文档找到了答案 Resource Management在上一节通过 ...

随机推荐

  1. powerdesigner 16.5 破解步骤

    假设你的PowerDesigner已经安装完成.(PowerDesigner下载地址:http://pan.baidu.com/s/1mgqjmpa) 1. 从网上下载PowerDesigner165 ...

  2. 解决 PowerDesigner 错误 The generation has been cancelled because errors have been found by the check model.

    在通过概念数据模型生成为物理数据模型时出现错误“The generation has been cancelled because errors have been found by the chec ...

  3. 刷新SqlServer所有视图元数据的存储过程

    摘自: http://www.cnblogs.com/yashen/archive/2004/12/23/81000.html 我们在使用SqlServer时经常遇到这种情况,当修改某个表的结构后,相 ...

  4. js版根据经纬度计算多边形面积(墨卡托投影)

    [摘要:var earthRadiusMeters = 6371000.0; var metersPerDegree = 2.0 * Math.PI * earthRadiusMeters / 360 ...

  5. Python - 带参数的方法

    import math class Point: def move(self, x, y): self.x = x self.y = y def reset(self): self.move(0, 0 ...

  6. iOS 本地通知 操作

    iOS 本地通知 操作 1:配置通知:然后退出程序: UILocalNotification *localNotif = [[UILocalNotification alloc] init]; loc ...

  7. PHP - AJAX 与 PHP

    PHP - AJAX 与 PHP AJAX 被用于创建交互性更强的应用程序. AJAX PHP 实例 下面的实例将演示当用户在输入框中键入字符时,网页如何与 Web 服务器进行通信: 实例 尝试在输入 ...

  8. ios开发之-继承的实现运用

    // // main.m // 继承 // // #import <Foundation/Foundation.h> #import "Animal.h" #impor ...

  9. 从CM刷机过程和原理分析Android系统结构

    前面101篇文章都是分析Android系统源代码,似乎不够接地气. 假设能让Android系统源代码在真实设备上跑跑看效果,那该多好.这不就是传说中的刷ROM吗?刷ROM这个话题是老罗曾经一直避免谈的 ...

  10. Reusing dialogs with a dialog pool--一个sql server service broker例子

    一个sql server service broker例子 ----------------------------------- USE master GO -------------------- ...