通过网络请求获取当前IP,并得到大致位置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过网络请求获取当前IP,并得到大致位置相关的知识,希望对你有一定的参考价值。

参考技术A 前段时间,项目有一个需求,就是获取用户的大致位置,国内精确到省市,国外有国家就可以。这种一般都是通过获取用户当前的IP地址,然后根据IP地址解析出所在的地区。网上也有很多方案,无非都是通过访问一个接口,然后解析返回的数据,例如:

站长之家: http://ip.chinaz.com/ipbatch

还有另外的提供商,不再一一说明。

这里就需要两个步骤:1.先得到用户的ip。2.再根据ip进行解析。
获取用户ip的方式,网上有很多,过程比较复杂,要处理局域网、ipv4,ipv6等多种情况,很麻烦。

我无意中发现了淘宝的这个网站:
http://ip.taobao.com/

可耐的淘宝程序猿们还专门写了个接口,供我们使用:

他也可以根据ip获取位置信息,你以为我要说的就这些了?看下面:
如果我这么请求:
http://ip.taobao.com/service/getIpInfo.php?ip=myip
我把ip字段的参数设置为myip,就直接省略了获取ip的步骤,返回的数据就是当前的位置信息json串儿!棒不棒?不知道为啥他们没说明这个参数,好可惜啊,估计很多同行都不知道这个。【知道的就不要拍砖了~】

我是高中生侦探工藤一号,会时不时的分享一些小技巧给大家~

java根据IP获取当前区域天气信息

大致思路是客户端发起请求,我们首先根据请求获取到外网IP,然后再根据外网IP获取到用户所在城市,最后根据城市获取到天气信息

获取外网IP

万网获取外网IP地址: www.net.cn/static/cust…

/**
 * @Description:获取客户端外网ip 此方法要接入互联网才行,内网不行
 **/
public static String getPublicIp() {
    try {
        String path = "http://www.net.cn/static/customercare/yourip.asp";// 要获得html页面内容的地址(万网)

        URL url = new URL(path);// 创建url对象

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 打开连接

        conn.setRequestProperty("contentType", "GBK"); // 设置url中文参数编码

        conn.setConnectTimeout(5 * 1000);// 请求的时间

        conn.setRequestMethod("GET");// 请求方式

        InputStream inStream = conn.getInputStream();
        // readLesoSysXML(inStream);

        BufferedReader in = new BufferedReader(new InputStreamReader(
                inStream, "GBK"));
        StringBuilder buffer = new StringBuilder();
        String line;
        // 读取获取到内容的最后一行,写入
        while ((line = in.readLine()) != null) {
            buffer.append(line);
        }
        List<String> ips = new ArrayList<>();

        //用正则表达式提取String字符串中的IP地址
        String regEx="((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)";
        String str = buffer.toString();
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        while (m.find()) {
            String result = m.group();
            ips.add(result);
        }

        // 返回公网IP值
        return ips.get(0);

    } catch (Exception e) {
        System.out.println("获取公网IP连接超时");
        return "";
    }
} 

根据外网IP获取用户所在城市

首先你待需要一个ip2region.db文件,大家可以百度一下

ip2region 准确率99.9%的ip地址定位库,0.0x毫秒级查询,数据库文件大小只有1.5M,提供了java,php,c,python,nodejs,golang查询绑定和Binary,B树,内存三种查询算法

引入ip2region.db

maven依赖

<!--ip2region-->
<dependency>
    <groupId>org.lionsoul</groupId>
    <artifactId>ip2region</artifactId>
    <version>1.7.2</version>
</dependency> 

创建IPUtils工具类

@Log4j2
public class IPUtils {

    /**
     * 根据IP获取地址
     *
     * @return 国家|区域|省份|城市|ISP
     */
    public static String getAddress(String ip) {
        return getAddress(ip, DbSearcher.BTREE_ALGORITHM);
    }

    /**
     * 根据IP获取地址
     *
     * @param ip
     * @param algorithm 查询算法
     * @return 国家|区域|省份|城市|ISP
     * @see DbSearcher
     * DbSearcher.BTREE_ALGORITHM; //B-tree
     * DbSearcher.BINARY_ALGORITHM //Binary
     * DbSearcher.MEMORY_ALGORITYM //Memory
     */
    @SneakyThrows
    public static String getAddress(String ip, int algorithm) {
        if (!Util.isIpAddress(ip)) {
            log.error("错误格式的ip地址: {}", ip);
            return "";
        }
        String dbPath = IPUtils.class.getResource("/db/ip2region.db").getPath();
        File file = new File(dbPath);
        if (!file.exists()) {
            log.error("地址库文件不存在");
            return "";
        }
        DbSearcher searcher = new DbSearcher(new DbConfig(), dbPath);
        DataBlock dataBlock;
        switch (algorithm) {
            case DbSearcher.BTREE_ALGORITHM:
                dataBlock = searcher.btreeSearch(ip);
                break;
            case DbSearcher.BINARY_ALGORITHM:
                dataBlock = searcher.binarySearch(ip);
                break;
            case DbSearcher.MEMORY_ALGORITYM:
                dataBlock = searcher.memorySearch(ip);
                break;
            default:
                log.error("未传入正确的查询算法");
                return "";
        }
        searcher.close();
        return dataBlock.getRegion();
    } 

根据城市获取天气信息

第三方天气接口:portalweather.comsys.net.cn/weather03/a…

调用第三方天气接口获取天气信息,本文使用java自带工具类HttpUtils

@GetMapping("/weather")
@DecryptBody(encode = true) //响应加密
public Result getWeather(){
    String publicIp = GetIPUtils.getPublicIp();//获取外网IP
    if (StringUtils.isBlank(publicIp)) return ResultUtils.error("获取失败");
    String cityInfo = IPUtils.getAddress(publicIp);//国家|区域|省份|城市|ISP
    if (StringUtils.isBlank(cityInfo)) return ResultUtils.error("获取失败");
    String[] split = cityInfo.split("\\|");
    String city = "";
    for (String aSplit : split) if (aSplit.contains("市")) city = aSplit;//拿取市级名称
    if (StringUtils.isBlank(city)) return ResultUtils.error("获取失败");
    String weatherInformation = HttpUtil.get("http://portalweather.comsys.net.cn/weather03/api/weatherService/getDailyWeather?cityName=" + city);//调用天气接口
    if (StringUtils.isBlank(weatherInformation)) return ResultUtils.error("获取失败");
    Object o = ObjectMapperUtils.strToObj(weatherInformation,Object.class);
    return ResultUtils.success("获取成功",o);
} 

以上是关于通过网络请求获取当前IP,并得到大致位置的主要内容,如果未能解决你的问题,请参考以下文章

请问java获取请求对象的电脑ip和网络ip的方法是啥?

iphone查看网络请求

找不到网络路径

(whh仅供自己参考)进行ip网络请求的步骤

winForm中如何实现网络请求WebAPI获取数据

09-文件和网络请求