您的位置:首页 > 新闻资讯 >文章内容
构建一个你的爬虫代理IP池
来源:互联网 作者:admin 时间:2019-09-02 10:35:52

  网站现在对于单个IP的访问频次都有严格的监控,特别是像一些大型网站,这样单个IP很容易被封。如果手上没有足够的IP,项目也无法完成,当我们在做某个项目或是爬虫的时,需要大量IP的话,我们可以考虑去搭建一个专门的代理IP池。


构建一个你的爬虫代理IP池


  获取IP的方式主要有以下几种:


  1、在平台购买现成收费的代理ip,ip质量高,高匿安全稳定,ip速度快,从而节约更多的时间去增加工作效率。比如机灵代理这类专业的IP代理商,搭配自建IP池以及专业的售前售后客服团队。


  2、从免费的网站上获取,获取的工作量非常大,ip可用率低,质量没有保障,获取到仅有的ip还未必安全,所以一般专业爬虫的工作者,不会去抓取免费代理ip。


  3、自己搭建代理服务器,建立独立机房,完全按自己的要求去搭建,代理ip绝对完美,但是搭建成本非常高,后期还需要专业的人定期代理维护,在性价比的情况下,还是不太适合适用。


  本文的代理IP池是通过爬虫事先从多个免费网站上获取代理IP之后,再做检查判断IP是否可用,可用的话就存放到MongoDB中,最后展示到前端的页面上。


  获取可用Proxy


  获取代理的核心代码是ProxyManager,它采用RxJava2来实现,主要做了以下几件事:


  创建ParallelFlowable,针对每一个提供免费代理IP的页面并行地抓取。


  Flowable.fromIterable(ProxyPool.proxyMap.keySet())

  .parallel()

  针对每一个页面进行抓取,返回List

  map(new Function() {

  @Override

  public List apply(String s) throws Exception {

  try {

  return new ProxyPageCallable(s).call();

  } catch (Exception e) {

  e.printStackTrace();

  }

  return null;

  }

  })

  对每一个页面获取的代理IP列表进行校验,判断是否可用

  flatMap(new Function() {

  @Override

  public Publisher apply(List proxies) throws Exception {

  if (proxies == null) return null;

  List result = proxies .stream()

  .parallel()

  .filter(new Predicate() {

  @Override

  public boolean test(Proxy proxy) {

  HttpHost httpHost = new HttpHost(proxy.getIp(), proxy.getPort(), proxy.getType());

  return HttpManager.get().checkProxy(httpHost);

  }

  }).collect(Collectors.toList());

  return Flowable.fromIterable(result);

  }

  })

  依次保存到proxyList

  subscribe(new Consumer() {

  @Override

  public void accept(Proxy proxy) throws Exception {

  log.debug("Result Proxy = "+proxy.getType()+"://"+proxy.getIp()+":"+proxy.getPort());

  proxy.setLastSuccessfulTime(new Date().getTime());

  ProxyPool.proxyList.add(proxy);

  }

  });

  ProxyManager代码:

  import com.cv4j.proxy.domain.Proxy;import com.cv4j.proxy.http.HttpManager;import com.cv4j.proxy.task.ProxyPageCallable;import io.reactivex.Flowable;import io.reactivex.functions.Consumer;import io.reactivex.functions.Function;import lombok.extern.slf4j.Slf4j;import org.apache.http.HttpHost;import org.reactivestreams.Publisher;import org.springframework.stereotype.Component;import java.util.Date;import java.util.List;import java.util.function.Predicate;import java.util.stream.Collectors;/**

  * Created by tony on 2017/10/25.

  */@Slf4j@Componentpublic class ProxyManager {

  /**

  * 抓取代理,成功的代理存放到ProxyPool中

  */

  public void start() {

  Flowable.fromIterable(ProxyPool.proxyMap.keySet())

  .parallel()

  .map(new Function() {

  @Override

  public List apply(String s) throws Exception {

  try {

  return new ProxyPageCallable(s).call();

  } catch (Exception e) {

  e.printStackTrace();

  }

  return null;

  }

  })

  .flatMap(new Function() {

  @Override

  public Publisher apply(List proxies) throws Exception {

  if (proxies == null) return null;

  List result = proxies .stream()

  .parallel()

  .filter(new Predicate() {

  @Override

  public boolean test(Proxy proxy) {

  HttpHost httpHost = new HttpHost(proxy.getIp(), proxy.getPort(), proxy.getType());

  return HttpManager.get().checkProxy(httpHost);

  }

  }).collect(Collectors.toList());

  return Flowable.fromIterable(result);

  }

  })

  .sequential()

  .subscribe(new Consumer() {

  @Override

  public void accept(Proxy proxy) throws Exception {

  log.debug("Result Proxy = "+proxy.getType()+"://"+proxy.getIp()+":"+proxy.getPort());

  proxy.setLastSuccessfulTime(new Date().getTime());

  ProxyPool.proxyList.add(proxy);

  }

  });

  }}

  定时任务

  每隔几个小时跑一次定时任务,在抓取完任务之后先删除旧的数据,然后再把新的数据插入到MongoDB中。

  import com.cv4j.proxy.ProxyManager;import com.cv4j.proxy.ProxyPool;import com.cv4j.proxy.dao.ProxyDao;import com.cv4j.proxy.domain.Proxy;import com.safframework.tony.common.utils.Preconditions;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;import java.util.concurrent.CopyOnWriteArrayList;/**

  * Created by tony on 2017/11/22.

  */@Componentpublic class ScheduleJobs {

  @Autowired

  ProxyDao proxyDao;

  @Autowired

  ProxyManager proxyManager;

  /**

  * 每六个小时跑一次任务

  */

  @Scheduled(cron = "0 0 */6 * * ?")

  public void cronJob() {

  System.out.println("Job Start...");

  proxyManager.start();

  CopyOnWriteArrayList list = ProxyPool.proxyList;

  // 先删除旧的数据

  proxyDao.deleteAll();

  // 然后再进行插入新的proxy

  if (Preconditions.isNotBlank(list)) {

  for (Proxy p:list) {

  proxyDao.saveProxy(p);

  }

  }

  System.out.println("Job End...");

  }}


  展示到前端

  在使用前,还可以再做一次检测,只要双击某个代理IP即可。

  在第二次检测时,对于已经失效的IP会被ProxyPool删除。


相关文章内容简介
推荐阅读
  • 30 2019-10
    换IP提高邮件营销成功率

    邮件营销虽然现在已经不是作为线上营销的主要部分,但是它的存在还是很有必要的,通过邮件这个渠道,能够将消息传递给客户。但是要注意的是,邮件发送也是有技巧的。

  • 17 2020-01
    网赚也能用代理ip?

    目前网赚行业谋利的方式太多,搜索赚钱、任务赚钱、介绍赚钱、调查赚钱、游戏赚钱等等皆应运而生,在这网络销售背后,必须要有一些辅助优化工具才能发挥至强大。各网站流量点击率都必

  • 18 2019-05
    滥用代理IP后果

    滥用代理IP后果,很少人会关注,都是看着别人用得好,自己也想用。而毫无章法的使用,其效果使真的使一言难尽。举个例子:

  • 26 2021-04
    http代理是什么意思

    很多人都知道,无论是在网上查询什么,还是查阅网站,我们都需要进入http。其实这是浏览器和web之间的一个服务器,也是在文本传输协议上的一种浏览方式。

  • 27 2020-11
    什么样的ip代理成本最低呢

    随着互联网的快速发展,互联网公司是否已经开始收集和分析大数据,并建立自己的大型数据库,催生了无数的数据收集公司,这就是我们所说的网络爬虫/网络蜘蛛。网络爬虫在数据采集过程

  • 06 2021-05
    动态ip地址特点介绍

    如今,我们的日常用品几乎离不开互联网。互联网功能:实现信息交流、资源共享、网上购物、网上外卖、网上购票等。每台计算机都需要一个IP地址才能访问互联网。因为IP地址资源宝贵,所

在线咨询
大客户经理
大客户经理
1829380381
13316264505

大客户经理微信

微信公众号

微信公众号

回到顶部