zoukankan      html  css  js  c++  java
  • GuozhongCrawler看准网爬虫动态切换IP漫爬虫

    有些关于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(" ");
                }
                
                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>



    搞定。

  • 相关阅读:
    Qt 去除控件边框线
    Qt 自定义可编辑 模型视图
    Qt double类型输出问题
    vue实例
    初识vue
    python中的数据类型
    python 列表解析式
    Goland常用快键键 mac pro
    文档对象模型DOM
    正则表达式
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7294747.html
Copyright © 2011-2022 走看看