wanghongsha 2020-01-17
代理是爬虫技术中很重要的一项。因为有一些网站会有相应的安全策略。例如检测一段时间内,某个IP地址的访问次数,如果访问频率过高,说明你不是正常访客,然后禁止你这个IP的访问。
应对这种机制有两种手段:
HttpClient支持设置代理。
CloseableHttpClient httpclient = HttpClients.createDefault(); /** * 第一种方式:最简单 * proxyHost:代理IP * proxyPort:代理端口号 * 注意:new HttpHost()是支持指定协议类型的,但是httpClient不默认支持socks协议, * 所以如果我们把上面代码中的协议改成new HttpHost("proxyHost", proxyPort, "SOCKS"),会报错。 */ HttpHost proxy = new HttpHost("proxyHost", 900, "HTTP"); HttpGet get = new HttpGet("192.168.1.1:8080/findUser"); CloseableHttpResponse response = httpclient.execute(proxy, get);
CloseableHttpClient httpclient = HttpClients.createDefault(); /** * 第二种方式 */ HttpGet httpGet = new HttpGet("192.168.1.1:8080/findUser"); httpGet.setConfig( RequestConfig.custom() .setProxy(new HttpHost("proxyHost", proxyPort, "HTTP")) .build() ); CloseableHttpResponse response = httpclient.execute(httpGet);
/** * 第三种方式:使用RoutePlanner */ HttpClientBuilder httpClientBuilder = HttpClients.custom(); //<1> 使用默认 HttpHost proxy = new HttpHost("proxyHost", proxyPort); DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy); httpClientBuilder.setRoutePlanner(routePlanner); //<2>或者使用标准的JRE代理选择器,即使用系统代理 SystemDefaultRoutePlanner systemRoutePlanner = new SystemDefaultRoutePlanner( ProxySelector.getDefault()); httpClientBuilder.setRoutePlanner(systemRoutePlanner ); CloseableHttpClient httpClient = httpClientBuilder.build();
1. RoutePlanner
在httpClient的请求执行过程中,HttpRoute首先出现在请求执行链的入口处,在进入请求执行链之前,使用routePlanner来根据目标主机、请求和请求上下文来计算出HttpRoute。详见InternalHttpClient#doExecute源码。
HttpClient默认计算HttpRoute的算法大致为:
2. 如何设置系统代理
注:系统代理配置指的 JVM 系统,而不是操作系统。
使用Java System类可以设置 HTTP 代理,HTTPS 代理和 SOCKS 代理:
// HTTP 代理,只能代理 HTTP 请求 System.setProperty("http.proxyHost", "127.0.0.1"); System.setProperty("http.proxyPort", "9876"); // HTTPS 代理,只能代理 HTTPS 请求 System.setProperty("https.proxyHost", "127.0.0.1"); System.setProperty("https.proxyPort", "9876"); // 同时支持代理 HTTP/HTTPS 请求 System.setProperty("proxyHost", "127.0.0.1"); System.setProperty("proxyPort", "9876"); // SOCKS 代理,支持 HTTP 和 HTTPS 请求 // 注意:如果设置了 SOCKS 代理就不要设 HTTP/HTTPS 代理 System.setProperty("socksProxyHost", "127.0.0.1"); System.setProperty("socksProxyPort", "1080");
当然也可以使用JVM命令行参数,如果是IDE项目,可以在启动设置中设置JVM 参数: