測試查詢ip地理位置的api調用情況

嘗試多個查詢ip地理位置的api

首先看代碼:

public static void main(String[] args) throws UnsupportedEncodingException {
		long l = System.currentTimeMillis();
		for (int i = 0; i < 100; i++) {
		System.out.println(getIpLocation("114.114.114.114"));
		}
		long l1 = System.currentTimeMillis();
		System.out.println("總耗時: "+(l1-l) + "ms");
	}


 public static String getIpLocation(String ip) {
		//只能支持少量低頻次調用,做了限流,循環100條只有前6次成功,後面都是限流失敗,4631ms
			String taobaoApi = "http://ip.taobao.com/service/getIpInfo.php?ip="+ip;
			//已經關閉
			String sinaApi = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip="+ip;
			//需要ak參數(註冊賬號),有併發限制,100條6357ms,普通已認證開發者賬號1天3w請求,未認證1天1k,限流1秒10次,網址 http://lbsyun.baidu.com/apiconsole/auth/privilege
			//並且返回的中文是unicode編碼,很坑
			String baiduApi = "http://api.map.baidu.com/location/ip?ak=xxxxxxx&ip="+ip;
			//返回頁面
			String pconlineApi = "https://whois.pconline.com.cn/?ip="+ip;
			//速度尚可 100條4521ms
			String ws126Api = "http://ip.ws.126.net/ipquery?ip="+ip;
			//速度很慢,一個月免費3w條,100條24808ms,apiKey需要註冊賬號
			String geoApi = "https://api.ipgeolocation.io/ipgeo?apiKey=xxxxxxx&ip="+ip;
			//速度很慢,100條79133ms
			String ip_Api = "http://ip-api.com/json/?ip="+ip;
			//一個月3w條免費, 100條耗時 37394ms
			String ipapi = "https://ipapi.co/"+ip+"/json";
			HttpResult httpResult = HttpClientUtil.get(baiduApi);
			if (HttpClientUtil.is200OK(httpResult)){
				return httpResult.getRespStr();
			}
			return "無法確定";
		}

其中嘗試了好幾種api,包括淘寶的,新浪的,百度的,以及國外的。(國外的返回的地址是拼音,準確的說是地址的英文)

其中大多都有併發限制和額度限制。而且返回速度有快有慢,我以100條測試,基本最快也要5秒,最慢可達1分鐘。

其中有一些比較坑,比如淘寶的api,使用瀏覽器和postman都可以正常調用,但是使用HttpClient就返回不了數據,後面發現需要將User-Agent 改爲postman或者chrome, 讓淘寶api以爲你是頁面調用的。默認HttpClient的User-Agent是Apache-HttpClient/4.5.10 (Java/1.8.0_181)

最後附上HttpClientUtil的代碼:

package com.zgd.base.spring.util.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.models.Scheme;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.http.MediaType;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * HttpClientUtil
 *
 * @author zgd
 * @date 2019/8/13 15:46
 */
@Slf4j
public class HttpClientUtil {

  private static HttpClient httpClient;

  public static HttpResult get(String url) {
    return get(url, null);
  }

  static {
    getHttpClient();
  }

  /**
   * 發起get請求
   *
   * @return java.lang.String
   * @author zgd
   * @date 2019/8/13 15:52
   */
  public static HttpResult get(String url, List<NameValuePair> params) {
    HttpGet get = null;
    try {

      URIBuilder uriBuilder = new URIBuilder(url);
      uriBuilder.setCharset(StandardCharsets.UTF_8);
      if (CollectionUtils.isNotEmpty(params)) {
        uriBuilder.setParameters(params);
      }
      get = new HttpGet(uriBuilder.build());
      log.info("請求的參數 url: {}\treq: {}", get.getURI(), params);

      HttpResponse response = httpClient.execute(get);
      String resp = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
      int code = response.getStatusLine().getStatusCode();
      log.info("返回的信息 resp: {}", resp);
      return new HttpResult(code, resp);
    } catch (Exception e) {
      log.warn("請求異常 --  error!", e);
    } finally {
      if (get != null) {
        get.releaseConnection();
      }
    }
    return null;
  }

  /**
   * 發送POST請求(普通表單形式)
   *
   * @return java.lang.String
   * @author zgd
   * @date 2019/8/13 15:56
   */
  public static HttpResult postForm(String url, HashMap<String, String> form) {
    List<BasicNameValuePair> params = form.entrySet().stream().map(en -> new BasicNameValuePair(en.getKey(), en.getValue()))
            .collect(Collectors.toList());
    HttpEntity entity = new UrlEncodedFormEntity(params, StandardCharsets.UTF_8);
    return postRequest(url, MediaType.APPLICATION_FORM_URLENCODED_VALUE, entity);
  }


  /**
   * 發送POST請求(JSON形式)
   *
   * @return java.lang.String
   * @author zgd
   * @date 2019/8/13 15:56
   */
  public static HttpResult postJSON(String url, String json) {
    StringEntity entity = new StringEntity(json, StandardCharsets.UTF_8);
    return postRequest(url, MediaType.APPLICATION_JSON_VALUE, entity);
  }


  /**
   * 發送post請求
   *
   * @param url
   * @param mediaType
   * @param entity
   * @return
   */
  public static HttpResult postRequest(String url, String mediaType, HttpEntity entity) {
    log.info("[postRequest] resourceUrl: {}", url);
    HttpPost post = null;
    try {
      URIBuilder uriBuilder = new URIBuilder(url);
      post = new HttpPost(uriBuilder.build());
      post.addHeader(HttpHeaders.CONTENT_TYPE, mediaType);
      post.setEntity(entity);
      HttpResponse response = httpClient.execute(post);
      String resp = EntityUtils.toString(response.getEntity());
      int code = response.getStatusLine().getStatusCode();
      log.info("返回的信息 resp:{}", resp);
      return new HttpResult(code, resp);
    } catch (Exception e) {
      log.warn("請求異常 --  error!", e);
    } finally {
      if (post != null) {
        post.releaseConnection();
      }
    }
    return null;
  }


  public static boolean is200OK(HttpResult result) {
    return result != null && result.getCode() == HttpStatus.SC_OK;
  }


  public static String getValue(HttpResult result, String key) {
    if (is200OK(result)) {
      try {
        JSONObject jsonObject = JSON.parseObject(result.getRespStr());
        return jsonObject.getString(key);
      } catch (Exception e) {
        log.warn("解析失敗 ", e);
      }
    }
    return null;
  }


  /**
   * 獲取默認的httpClient
   *
   * @return
   */
  public static HttpClient getHttpClient() {
    if (httpClient == null) {
      RequestConfig requestConfig = RequestConfig.custom()
              .setConnectTimeout(3000)
              .setConnectionRequestTimeout(3000)
              .setSocketTimeout(5000).build();
      httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig)
              .setMaxConnTotal(1000)
              .setMaxConnPerRoute(100)
              .setDefaultHeaders(getDefaultHeaders())
              .build();
    }
    return httpClient;
  }


  /**
   * 設置默認的請求頭
   *
   * @return
   */
  public static List<Header> getDefaultHeaders() {
    List<Header> headers = new ArrayList<>();
    headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36"));
    headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate"));
    headers.add(new BasicHeader("Accept-Language", "zh-CN"));
    headers.add(new BasicHeader("Connection", "Keep-Alive"));
    headers.add(new BasicHeader("Accept", "*/*"));
    return headers;
  }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章