1

使用IP获取地理位置信息

  最近博客刚写了一个地理信息统计的功能,想看看来访我博客的网友都来自哪些地区,这要用到IP地理信息查询接口,网上有很多大厂(如腾讯,淘宝,搜狐等等)或地理信息机构开放的IP地理信息查询API,我之前使用过一个搜狐的,获取的地理信息有时候不准确,果断丢弃,换成了腾讯地图开放平台免费限量的IP信息查询API,限量是每天1w的固定调用次数,每秒5次的并发量,虽然不多,玩玩是可以的, 如果你的需求远大于1万, 就可以考虑升级为企业开发者用户了, 提交企业资质, 能免费得到每天300万次调用,每秒500次的并发.
  没有使用过的童鞋需要正在腾讯地图开放平台进行几个步骤才可以使用:
    1.注册为开发者并验证
    2.key与配额,并生成一个key即可,
    3.IP定位查询接口开放文档在--WebService API菜单下-- IP定位
    4.支持JSON/JSONP,默认JSON,很方便,
    5.能得到: 定位坐标(包含经纬度),国家,省,市,区,和行政划分代号

使用Java调用IP定位查询接口

  1. 我的需求很简单, 使用ip作为参数调用IP定位查询接口, 得到该ip是属于国内哪个省市区, 或者其他国家.
  2. 准备几个配置字段
    a. geogQueryAPI 接口url
    b. dayCount=10000 一天调用次数上限 (1w)
    c. concurrentTime=1000 并发单位 1秒(1000毫秒)
    d. concurrentCount=5 并发次数 5次
  3. java调用代码

public static void main(String[] args) {
        String ip = "112.115.91.165";
        // 接口url
        String geogQueryAPI = "https://apis.map.qq.com/ws/location/v1/ip?key=xxxx";
        int requestedCount = cache.get("requestedCount");
        // 检测是否超出一天1w调用次数上限, 超出后明日才可调用
        if (requestedCount > dayCount) {
            // 超出一天调用次数上限,其他处理
        } else {
            // 调用腾讯IP查询,得到geogJson地理位置信息数据
            String geogJson = queryGeogByIP(ip, geogQueryAPI);
            cache.put("requestedCount", ++requestedCount);
        }
    }
    /**
     * 调用腾讯IP查询地理位置
     *
     * @param ip
     * @return
     */
    public static String queryGeogByIP(String ip, String geogQueryAPI) {
        String response = null;
        if (interval()) {
            response = HTTP.get(geogQueryAPI + "&ip=" + ip);
            // 记录最后请求时间戳
            lastRequestMillisecond = System.currentTimeMillis();
        }
        return response;
    }
    // 最后请求时间
    private static long lastRequestMillisecond = new Long("1583649119658");
    /**
     * 间隔计算
     * 说明: 腾讯接口调用要求,每秒并发不得超过5次,
     * 防止每秒并发超过5次而导致错误响应,
     * 且也不浪费每秒5次的请求次数,正好保存在5次以内
     * 最低间隔区间: 1000 / 5 最低间隔 200毫秒
     *
     * @return 是否可以请求
     */
    private static boolean interval() {
        // 最低并发间隔
        long concurrentInterval = concurrentTime / concurrentCount;
        // 当前时间戳
        long thisMillisecond = System.currentTimeMillis();
        // 距离上一次调用毫秒差
        long interval = thisMillisecond - lastRequestMillisecond;
        if (interval < concurrentInterval) {
            // 间隔时间不够最低并发的间隔,计算沉睡多久正好开始调用
            long sleepMillisecond = concurrentInterval - interval;
            try {
                Thread.sleep(sleepMillisecond);
            } catch (InterruptedException e) {
            }
        }
        return true;
    }

4.最后调用结果geogJson响应如下

{
    "status": 0,
    "message": "query ok",
    "result": {
        "ip": "112.115.91.165",
        "location": {
            "lat": 24.87966,
            "lng": 102.83322
        },
        "ad_info": {
            "nation": "中国",
            "province": "云南省",
            "city": "昆明市",
            "district": "",
            "adcode": 530100
        }
    }
}

Vic_
5 声望0 粉丝

码农一枚