设置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代理池相关推荐

  1. 免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作简易流量爬虫...

    前言 我们之前的爬虫都是模拟成浏览器后直接爬取,并没有动态设置IP代理以及UserAgent标识,这样很容易被服务器封IP,因此需要设置IP代理,但又不想花钱买,网上有免费IP代理,但大多都数都是不可 ...

  2. 爬虫(第一篇) IP代理池

    搞虫子的都知道,IP代理是必要的方法,为什么?这个大家知道就好了,最近写了个IP代理池,给大家围观一下:开始. 首先咱们找到一个免费的IP代理网站,读取人家的数据,但是注意了,注意频率 别把人家给搞崩 ...

  3. (廿九)Python爬虫:IP代理池的开发

    作为一个爬虫开发者,使用IP代理是必要的一步,我们可以在网上找到免费的高匿IP,比如西刺代理.但是,这些免费的代理大部分都是不好用的,经常会被封禁.所以我们转而考虑购买付费代理.可是,作为一个程序员首 ...

  4. Python使用Redis实现IP代理池

    可以使用快代理,芝麻代理,蘑菇代理 ,讯代理等代理商提供API代理IP或者免费代理建立自己IP代理池 #使用apscheduler库定时爬取ip,定时检测ip删除ip,做了2层检测,第一层爬取后放入r ...

  5. python ip代理池_python实现ip代理池功能示例

    本文实例讲述了python实现ip代理池功能.分享给大家供大家参考,具体如下: 爬取的代理源为西刺代理. 用xpath解析页面 用telnet来验证ip是否可用 把有效的ip写入到本地txt中.当然也 ...

  6. 爬虫学习笔记(十)—— Scrapy框架(五):下载中间件、用户/IP代理池、settings文件

    一.下载中间件 下载中间件是一个用来hooks进Scrapy的request/response处理过程的框架. 它是一个轻量级的底层系统,用来全局修改scrapy的request和response. ...

  7. 开源IP代理池续——整体重构

    开源IP代理池 继上一篇开源项目IPProxys的使用之后,大家在github,我的公众号和博客上提出了很多建议.经过两周时间的努力,基本完成了开源IP代理池IPProxyPool的重构任务,业余时间 ...

  8. python通过ip池爬_python爬虫18 | 就算你被封了也能继续爬,使用IP代理池伪装你的IP地址,让IP飘一会...

    我们上次说了伪装头部 ↓ 让自己的 python 爬虫假装是浏览器 小帅b主要是想让你知道 在爬取网站的时候 要多的站在对方的角度想问题 其实 这和泡妞差不多 你要多站在妹纸的角度思考 她的兴趣是什么 ...

  9. python爬虫ip代理池_爬虫教程-Python3网络爬虫开发——IP代理池的维护

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 准备工作 要实现IP代理池我们首先需要成功安装好了 Redis 数据库并启动服务,另外还需要安装 Aiohttp.Requests.RedisPy.PyQ ...

最新文章

  1. html选择按钮selected,HTML Option defaultSelected用法及代码示例
  2. django admin扩展 相关备忘录
  3. python 获取windows上 网络连接信息 ip dhcp dns gateway
  4. 2.第一个HTML页面
  5. 【异常 1】什么是异常
  6. UI设计中标签栏图标设计规范
  7. 【单片机仿真】(十一)指令系统逻辑运算指令 — 逻辑与指令ANL、逻辑或指令ORL
  8. Panabit标准版免费版功能限制
  9. php要学ps吗,小蚂蚁学习PS切图(3)——小练习
  10. 改进的树状长短期记忆网络(Tree-LSTM)语义表示
  11. 明明有QQ,凭什么微信能火?——QQ微信横向对比分析
  12. 妥妥的世界第一:为什么MT4软件的地位无法撼动?
  13. Linux命令之ll
  14. Tensorflow-Keras教程
  15. android JavaMail报错:SendFailedException: No recipient addresses
  16. 斯坦福大学(吴恩达) 机器学习课后习题详解 第三周 逻辑回归
  17. 吹爆“Alibaba”自研Spring全家桶全套全彩学习笔记(终极版)
  18. 蓝桥杯 基础练习(三)字母图形 C语言
  19. Linux 操作系统之文件服务
  20. Window cmd

热门文章

  1. System.out.print(我爱你)
  2. python海伦公式求三角形面积程序流程图_《求三角形面积程序代码实现》教学设计...
  3. 告诉你外语学习的真实方法及误区分析(整理)
  4. Pyinstaller打包pygame包的aliens.py文件
  5. MODIS反射率产品MOD09GA、MYD09GA的下载与使用
  6. arduino灯光装置_创客实战 | 用Arduino制作一款奇幻的“灯光隧道”
  7. linux centos7 安装gc,Linux(Centos7)安装Java JDK及卸载
  8. Linux上使用SafeNet加密exe文件
  9. 台大-林轩田老师-机器学习基石学习笔记6
  10. 远程办公时意外摔伤,算工伤吗?