Java实现Ip代理池
设置Ip代理很多时候都会有用到,尤其是在写爬虫相关项目的时候。虽然自己目前没有接触这种需求,但由于最近比较闲,就写着当作练习吧
爬取代理IP
爬取
关于爬取代理IP,国内首先想到的网站当然是 西刺代理 。首先写个爬虫获取该网站内的Ip吧。
先对 国内Http代理 标签页面进行爬取,解析页面使用的Jsoup ,这里大概代码如下
private List<IPBean> crawl(String api, int index){String html = HttpUtils.getResponseContent(api + index);System.out.println(html);Document document = Jsoup.parse(html);Elements eles = document.selectFirst("table").select("tr");for (int i = 0; i < eles.size(); i++){if (i == 0) continue;Element ele = eles.get(i);String ip = ele.children().get(1).text();int port = Integer.parseInt(ele.children().get(2).text().trim());String typeStr = ele.children().get(5).text().trim();int type;if ("HTTP".equalsIgnoreCase(typeStr))type = IPBean.TYPE_HTTP;elsetype = IPBean.TYPE_HTTPS;IPBean ipBean = new IPBean(ip, port, type);ipList.add(ipBean);}return ipList;}
对某些不明白的变量,可以参考我Github
其中关键的就是css选择器语法,这里需要注意的是不要乱加空格,不然会导致找不到出现空指针。
css选择器语法具体参考这里 , 这里就不讲解了。
爬取的信息包括 ip地址、端口号、和代理类型(http或https), 这三个信息我放在IPBean这个类里面。
过滤
上面爬取完成后,还要进一步过滤,筛选掉不能使用的。
筛选大概原理就是先设置上代理,然后请求某个网页,若成功则代表此代理ip有效。
其中请求成功的标志我们可以直接获取请求的返回码,若为200即成功。
/*** 检测代理ip是否有效** @param ipBean* @return*/public static boolean isValid(IPBean ipBean) {Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipBean.getIp(), ipBean.getPort()));try {URLConnection httpCon = new URL("https://www.baidu.com/").openConnection(proxy);httpCon.setConnectTimeout(5000);httpCon.setReadTimeout(5000);int code = ((HttpURLConnection) httpCon).getResponseCode();System.out.println(code);return code == 200;} catch (IOException e) {e.printStackTrace();}return false;}
注意这里要设置两个超时,连接超时和读取超时。连接超时还好,它默认只是有点长;然而读取超时如果不设置,它好像就会一直阻塞着。
时间设置为5s就够了,毕竟如果ip有效的话,会很快就请求成功的。这样过滤后,就得到有效的代理ip了
设置代理
单次代理
单次代理表示只在这一次连接中有效,即每次都需要代理。
http方式的代理非常简单,在URL对象的openConnection方法中加上个Proxy对象即可
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipBean.getIp(), ipBean.getPort()));connection = (HttpsURLConnection) new URL(url).openConnection(proxy);
https 稍微复杂点了,中间加上了ssl协议
/*** @param url* @param headerMap 请求头部* @param ipBean* @return* @throws Exception*/public static String getResponseContent(String url, Map<String, List<String>> headerMap, IPBean ipBean) throws Exception {HttpsURLConnection connection = null;// 设置代理if (ipBean != null) {Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipBean.getIp(), ipBean.getPort()));connection = (HttpsURLConnection) new URL(url).openConnection(proxy);if (ipBean.getType() == IPBean.TYPE_HTTPS) {SSLContext sslContext = SSLContext.getInstance("SSL");sslContext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());connection.setSSLSocketFactory(sslContext.getSocketFactory());connection.setHostnameVerifier(new TrustAnyHostnameVerifier());}}if (connection == null)connection = (HttpsURLConnection) new URL(url).openConnection();// 添加请求头部connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36");if (headerMap != null) {Iterator<Map.Entry<String, List<String>>> iterator = headerMap.entrySet().iterator();while (iterator.hasNext()) {Map.Entry<String, List<String>> entry = iterator.next();List<String> values = entry.getValue();for (String value : values)connection.setRequestProperty(entry.getKey(), value);}}InputStream inputStream = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));StringBuilder stringBuilder = new StringBuilder();String line;while ((line = reader.readLine()) != null) {stringBuilder.append(line);}reader.close();inputStream.close();return stringBuilder.toString();}private static class TrustAnyTrustManager implements X509TrustManager {public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[]{};}}private static class TrustAnyHostnameVerifier implements HostnameVerifier {public boolean verify(String hostname, SSLSession session) {return true;}}
这里https方法参考了 这篇博客
全局代理
直接上代码,就几行代码
package util;import other.IPBean;/*** @author Asche* @github: https://github.com/asche910* @date 2019年1月19日*/
public class ProxyUtils {/*** 设置全局代理* @param ipBean*/public static void setGlobalProxy(IPBean ipBean){System.setProperty("proxyPort", String.valueOf(ipBean.getPort()));System.setProperty("proxyHost", ipBean.getIp());System.setProperty("proxySet", "true");}}
需要注意一点就是全局只是在该java项目中生效,它不会更改系统中的代理。
检测
设置完代理后,也可以用另外一种方法来判断是否代理成功,即直接获取当前ip地址。
这里我使用的是 https://www.ipip.net/ip.html 这个网站,请求获取html后再解析得到自己的当前ip
private static final String MY_IP_API = "https://www.ipip.net/ip.html";// 获取当前ip地址,判断是否代理成功public static String getMyIp() {try {String html = HttpUtils.getResponseContent(MY_IP_API);Document doc = Jsoup.parse(html);Element element = doc.selectFirst("div.tableNormal");Element ele = element.selectFirst("table").select("td").get(1);String ip = element.selectFirst("a").text();// System.out.println(ip);return ip;} catch (Exception e) {e.printStackTrace();}return null;}
优化
emmm 优化些啥呢???
速度
爬取ip时就几个网页,优化估计效果不大。而真正耗时的是检测ip是否有效,因此这里采用多线程,对每个ip的检测请求使用一个线程,最后副线程全部结束后再统计出有多少有效ip。然而问题又来了,怎么判断所有副线程全部结束了呢??? 脑中立刻想到的是join方法,然而仔细想想,才发现这样并不可取。最佳方法应该是设置一个计数器,每个线程结束后计数器加一,然后在主线程循环判断计数器的值是否与线程总数相等即可。由于涉及到并发,需要给某些方法加上锁。这里我代码中实现了,可以参考github
持久化
emmm 由于目前只是练练手,并没有这样的需求,比较懒, ( ̄▽ ̄)*
所以这个需求暂时放放吧,以后有时间再写
最后github入口:Asche910
Java实现Ip代理池相关推荐
- 免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作简易流量爬虫...
前言 我们之前的爬虫都是模拟成浏览器后直接爬取,并没有动态设置IP代理以及UserAgent标识,这样很容易被服务器封IP,因此需要设置IP代理,但又不想花钱买,网上有免费IP代理,但大多都数都是不可 ...
- 爬虫(第一篇) IP代理池
搞虫子的都知道,IP代理是必要的方法,为什么?这个大家知道就好了,最近写了个IP代理池,给大家围观一下:开始. 首先咱们找到一个免费的IP代理网站,读取人家的数据,但是注意了,注意频率 别把人家给搞崩 ...
- (廿九)Python爬虫:IP代理池的开发
作为一个爬虫开发者,使用IP代理是必要的一步,我们可以在网上找到免费的高匿IP,比如西刺代理.但是,这些免费的代理大部分都是不好用的,经常会被封禁.所以我们转而考虑购买付费代理.可是,作为一个程序员首 ...
- Python使用Redis实现IP代理池
可以使用快代理,芝麻代理,蘑菇代理 ,讯代理等代理商提供API代理IP或者免费代理建立自己IP代理池 #使用apscheduler库定时爬取ip,定时检测ip删除ip,做了2层检测,第一层爬取后放入r ...
- python ip代理池_python实现ip代理池功能示例
本文实例讲述了python实现ip代理池功能.分享给大家供大家参考,具体如下: 爬取的代理源为西刺代理. 用xpath解析页面 用telnet来验证ip是否可用 把有效的ip写入到本地txt中.当然也 ...
- 爬虫学习笔记(十)—— Scrapy框架(五):下载中间件、用户/IP代理池、settings文件
一.下载中间件 下载中间件是一个用来hooks进Scrapy的request/response处理过程的框架. 它是一个轻量级的底层系统,用来全局修改scrapy的request和response. ...
- 开源IP代理池续——整体重构
开源IP代理池 继上一篇开源项目IPProxys的使用之后,大家在github,我的公众号和博客上提出了很多建议.经过两周时间的努力,基本完成了开源IP代理池IPProxyPool的重构任务,业余时间 ...
- python通过ip池爬_python爬虫18 | 就算你被封了也能继续爬,使用IP代理池伪装你的IP地址,让IP飘一会...
我们上次说了伪装头部 ↓ 让自己的 python 爬虫假装是浏览器 小帅b主要是想让你知道 在爬取网站的时候 要多的站在对方的角度想问题 其实 这和泡妞差不多 你要多站在妹纸的角度思考 她的兴趣是什么 ...
- python爬虫ip代理池_爬虫教程-Python3网络爬虫开发——IP代理池的维护
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 准备工作 要实现IP代理池我们首先需要成功安装好了 Redis 数据库并启动服务,另外还需要安装 Aiohttp.Requests.RedisPy.PyQ ...
最新文章
- html选择按钮selected,HTML Option defaultSelected用法及代码示例
- django admin扩展 相关备忘录
- python 获取windows上 网络连接信息 ip dhcp dns gateway
- 2.第一个HTML页面
- 【异常 1】什么是异常
- UI设计中标签栏图标设计规范
- 【单片机仿真】(十一)指令系统逻辑运算指令 — 逻辑与指令ANL、逻辑或指令ORL
- Panabit标准版免费版功能限制
- php要学ps吗,小蚂蚁学习PS切图(3)——小练习
- 改进的树状长短期记忆网络(Tree-LSTM)语义表示
- 明明有QQ,凭什么微信能火?——QQ微信横向对比分析
- 妥妥的世界第一:为什么MT4软件的地位无法撼动?
- Linux命令之ll
- Tensorflow-Keras教程
- android JavaMail报错:SendFailedException: No recipient addresses
- 斯坦福大学(吴恩达) 机器学习课后习题详解 第三周 逻辑回归
- 吹爆“Alibaba”自研Spring全家桶全套全彩学习笔记(终极版)
- 蓝桥杯 基础练习(三)字母图形 C语言
- Linux 操作系统之文件服务
- Window cmd
热门文章
- System.out.print(我爱你)
- python海伦公式求三角形面积程序流程图_《求三角形面积程序代码实现》教学设计...
- 告诉你外语学习的真实方法及误区分析(整理)
- Pyinstaller打包pygame包的aliens.py文件
- MODIS反射率产品MOD09GA、MYD09GA的下载与使用
- arduino灯光装置_创客实战 | 用Arduino制作一款奇幻的“灯光隧道”
- linux centos7 安装gc,Linux(Centos7)安装Java JDK及卸载
- Linux上使用SafeNet加密exe文件
- 台大-林轩田老师-机器学习基石学习笔记6
- 远程办公时意外摔伤,算工伤吗?