
qq:800819103
在线客服,实时响应
qq群
在线客服,实时响应
客服电话
400-998-9776转3网站现在对于单个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删除。
连接网络的设备是非常脆弱的,需要设置防火墙,否则很容易被其他用户获取到我们的信息,让我们造成损失,因此防火墙是非常必须的。今天小编跟大家来聊聊代理防火墙,什么是代理防火墙
高效优质的代理IP是爬虫的利器,不然反爬虫策略太烦人,更烦人的是隔几天就升级一次反爬虫策略。虽说努力下,加加班什么的,还是能解决的,但是对方吃饱了没事干,过去啊三个月一次的
经过前面的长长铺垫,我们终于进入到Linux+NetCore+Nginx搭建负载集群的重头戏了。前方知识点比较多,代理IP建议细细查看,这样才是学习知识的正确姿势。相关阅读:如何搭建搭建负载集群(上)
网络时代我们很多操作都无法脱离互联网来完成,随着更多的工作以及生活应用需要网络,我们对互联网的操作就更加需要注意。
高质量的ip代理在网络爬虫中是非常关键的存在,如果没有一个有效的换ip软件,大家可能就无法保障爬虫工作的进程了。为了保持爬虫的效率及正常运行,用好的代理IP很重要。
现在,反爬虫是越来越严,不少人在吐槽现在爬虫不好做。面对平台的反爬虫规则,我们是一点办法都没有了吗?显然不是的,代理IP这就告诉你,怎么样可以减少被封的几率。