背景:
我们有个车管系统,需要定期的去查询车辆的违章,之前一直是调第三方接口去查,后面发现数据不准确(和深圳交警查的对不上),问题比较多。于是想干脆直接从深圳交警上查,那不就不会出问题了吗,但是问题又来了,因为车比较多,一次查的数据量很大,如果同时间段大批量请求深圳交警可能会导致ip被他们那边封禁,那有什么解决办法呢?
解决方案:
网上查了很多资料,大致讲的就是设置代理ip,然后通过代理ip去访问。
设置代理ip:
设置代理ip的方式有很多种,我这里讲其中一种,通过httpClient设置代理Ip,httpClient我想大家都不陌生了吧,它几乎封装了所有的http请求方法,当然其中也提供了设置代理ip的方法,废话不多说,直接上代码。
@Test public void test() throws Exception{ //创建httpClient实例 CloseableHttpClient httpClient = HttpClients.createDefault(); //创建httpGet实例 HttpPost httpPost = new HttpPost("请求地址"); //设置代理IP,设置连接超时时间 、 设置 请求读取数据的超时时间 、 设置从connect Manager获取Connection超时时间、 HttpHost proxy = new HttpHost("125.77.49.244", 808); List<NameValuePair> params = new ArrayList<NameValuePair>(); //设置请求参数 params.add(new BasicNameValuePair("car_number", "粤B123456")); params.add(new BasicNameValuePair("licensePlateNo", "粤B123456")); HttpEntity entitys = new UrlEncodedFormEntity(params, "UTF-8"); RequestConfig requestConfig = RequestConfig.custom() .setProxy(proxy) .setConnectTimeout(10000) .setSocketTimeout(10000) .setConnectionRequestTimeout(3000) .build(); httpPost.setConfig(requestConfig); httpPost.setEntity(entitys); //设置请求头消息 httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0"); CloseableHttpResponse response = httpClient.execute(httpPost); if (response != null){ HttpEntity entity = response.getEntity(); //获取返回实体 if (entity != null){ System.out.println("网页内容为:"+ EntityUtils.toString(entity,"utf-8")); } } if (response != null){ response.close(); } if (httpClient != null){ httpClient.close(); } } 这里讲一下另外一种设置代理ip的方案,直接上代码
@Test public void test3() throws Exception{ System.getProperties().setProperty("proxySet","true"); System.getProperties().setProperty("http.proxyHost","60.191.201.38"); //设置ip System.getProperties().setProperty("http.proxyPort","45461"); //设置端口号 Document cocument = Jsoup.connect("http://127.0.0.1:8082/newAtb/indexData.do").ignoreContentType(true).post(); } 至于代理ip,有很多种获取方式,大部分需要花钱买,免费的很少,这里给大家一个网站 http://www.xicidaili.com/,这个网站每天都会更新免费的代理ip,我们可以定期去上面爬取数据到本地供我们使用,这里贴上一段本人爬取ip的代码
public void setProxyIpList(){ try { String rLine; URL url = new URL("http://www.xicidaili.com/"); URLConnection conn = url.openConnection(); conn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 7.0; NT 5.1; GTB5; .NET CLR 2.0.50727; CIBA)"); List<String> list = new ArrayList<>(); InputStreamReader inputStreamReader = new InputStreamReader(conn.getInputStream(),"utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); int a = 0; do{ rLine = bufferedReader.readLine(); String reg1 = "\\d+"; //匹配端口号 String reg = "\\d+\\.\\d+\\.\\d+\\.\\d+"; //匹配ip if(rLine.contains("<td>") ) { rLine = rLine.substring(rLine.indexOf("<td>") + 4, rLine.indexOf("</td>")); if (Pattern.matches(reg, rLine) || Pattern.matches(reg1, rLine)) { list.add(rLine); a++; } } }while (a !=40); for (int i=0; i< list.size();i=i+2 ) { IPort ip = new IPort(); ip.setIp(list.get(i)); ip.setPort(Integer.parseInt(list.get(i+1))); listPort.add(ip); } } catch (Exception e) { e.printStackTrace(); logger.info("拉取代理ip异常:" + e.getMessage()); } }