设置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;
else
type = 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代理池跟UserAgent池,并制作 ...

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

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

  3. 记一次企业级爬虫系统升级改造(六):基于Redis实现免费的IP代理池

    前言: 首先表示抱歉,春节后一直较忙,未及时更新该系列文章. 近期,由于监控的站源越来越多,就偶有站源做了反爬机制,造成我们的SupportYun系统小爬虫服务时常被封IP,不能进行数据采集. 这时候 ...

  4. 爬取西刺ip代理池

    好久没更新博客啦~,今天来更新一篇利用爬虫爬取西刺的代理池的小代码 先说下需求,我们都是用python写一段小代码去爬取自己所需要的信息,这是可取的,但是,有一些网站呢,对我们的网络爬虫做了一些限制, ...

  5. scrapy_随机ip代理池

    什么是ip代理? 我们电脑访问网站,其实是访问远程的服务器,通过ip地址识别是那个机器访问了服务器,服务器就知道数据该返回给哪台机器,我们生活中所用的网络是局域网,ip是运营商随机分配的,是一种直接访 ...

  6. Python爬虫之ip代理池

    可能在学习爬虫的时候,遇到很多的反爬的手段,封ip 就是其中之一. 对于封IP的网站.需要很多的代理IP,去买代理IP,对于初学者觉得没有必要,每个卖代理IP的网站有的提供了免费IP,可是又很少,写了 ...

  7. 5 使用ip代理池爬取糗事百科

    从09年读本科开始学计算机以来,一直在迷茫中度过,很想学些东西,做些事情,却往往陷进一些技术细节而蹉跎时光.直到最近几个月,才明白程序员的意义并不是要搞清楚所有代码细节,而是要有更宏高的方向,要有更专 ...

  8. python开源IP代理池--IPProxys

    今天博客开始继续更新,谢谢大家对我的关注和支持.这几天一直是在写一个ip代理池的开源项目.通过前几篇的博客,我们可以了解到突破反爬虫机制的一个重要举措就是代理ip.拥有庞大稳定的ip代理,在爬虫工作中 ...

  9. python爬虫实战(三)--------搜狗微信文章(IP代理池和用户代理池设定----scrapy)

    在学习scrapy爬虫框架中,肯定会涉及到IP代理池和User-Agent池的设定,规避网站的反爬. 这两天在看一个关于搜狗微信文章爬取的视频,里面有讲到ip代理池和用户代理池,在此结合自身的所了解的 ...

随机推荐

  1. 20145218张晓涵_Exp5 MSF基础应用

    20145218张晓涵_Exp5 MSF基础应用 实验原理 MS08-067漏洞描述 MS08-067漏洞的全称为"Windows Server服务RPC请求缓冲区溢出漏洞",如果 ...

  2. element时间选择器插件转化为YYYY-MM-DD的形式

    let datete = new Date(this.form.value0);this.form.value0 =datete.getFullYear() +"-" +(date ...

  3. android 优秀图表库之MPAndroidChart

    MPAndroidChart 1.在项目当中很多时候要对数据进行分析就要用到图表,在gitHub上有很多优秀的图表开源库,这里就简单介绍一下MPAndroidChart. 他可以实现图表的拖动,3D, ...

  4. [日常]无线鼠标滚动缩放EXCEL表时,缩放比例过大问题

    这也是一个奇葩问题,解决方法: 把USB接收器拔掉重新插上,效果拔群

  5. Ubuntu 14.04.3 LTS如何安装谷歌输入法

    谷歌输入法项目主页:https://code.google.com/p/scim-googlepinyin/ 一,打开Ubuntu 的“Ubunru的软件中心”,在搜索里面输入“googlepinyi ...

  6. C语言#include的用法

    1.#include 命令介绍 #include 命令是预处理命令的一种,预处理命令可以将别的源代码内容插入到所指定的位置:可以标识出只有在特定条件下才会被编译的某一段程序代码: 可以定义类似标识符功 ...

  7. 【ARC080F】Prime Flip 差分+二分图匹配

    Description ​ 有无穷个硬币,初始有n个正面向上,其余均正面向下.  你每次可以选择一个奇质数p,并将连续p个硬币都翻转.  问最小操作次数使得所有硬币均正面向下. Input ​ 第一行 ...

  8. 使用带参数的SQL语句向数据库中插入空值

    private void button1_Click(object sender, EventArgs e) { string name = textBox1.Text; int age = Conv ...

  9. 查看SELinux状态及关闭SELinux

    查看SELinux状态: 输入:/usr/sbin/sestatus -v SELinux status: enabled           ##开启状态 关闭SELinux 修改vi /etc/s ...

  10. office 2013 破解工具 及 软件下载

     win7/win8/win10  office2013 破解工具 下载地址: https://pan.baidu.com/s/1sZeJOCWq1fZ3KIOWvmrAQQ office2013  ...