IP属地信息哪里来的?手把手教你实现通过IP查询属地信息

article/2025/10/14 15:35:05

本文主要讲解IP查询属地信息的实现方法,以及基于Spring Boot实现IP属地信息查询项目。

〇、前言

近日,多个网络公众平台纷纷公开显示用户的IP属地,并且用户无法开启或关闭此功能。

用户的IP信息,平台是怎么知道的?

其大致流程是这样的:

  • 用户的手机、电脑等设备必须通过网络运营商(电信、移动等)进行联网服务,这个连接网络的过程中,基站、路由器将为该设备动态分配一个IP
  • 用户发布一篇文章或微博,或者进行评论时,就会向平台服务器发送一个HTTP请求。而IP信息,就包含在这个HTTP请求头里;
  • 平台服务器接收到请求信息,就可以通过HTTP请求(Request请求)信息解析出该用户的IP

在这个过程中,请求信息只包含IP,并不包含用户的属地信息

另外,对于交互式平台来说,《互联网交互式服务安全管理要求》(GA 1277.1-2020)的第1部分 基本要求第8.3条 日志与用户数据记录明确,平台必须记录用户的活动、信息发布等操作的IP地址及源端口。详见:http://www.beian.gov.cn/portal/downloadcenter 。

平台如何通过IP查询到属地信息?

一种方案是请求第三方IP属地信息服务的API,通过该接口查询用户的IP属地信息。但这种方案通常是按量付费的,大的平台请求量巨大,不划算。

另外一种方案是使用离线的IP地址数据库,该数据库通常是一个文件,甚至可能是cvs文件、txt文件。

该数据库一般是由专业人士通过专业技术人工生成,其中记录了大量的IP地址(段),并记录了该IP地址(段)所属的国家省份城市运营商名称邮政编码经纬度等信息。

接下来,将基于JavaMaxMindIP地址数据库,讲解如何实现通过IP获取属地信息

一、下载IP地址库

提供离线IP地址数据库的平台有很多,比如:

  • http://www.ipip.net
  • https://user.ip138.com/ip/lib/

这些平台通常是付费的,价格不菲。不过也有平台提供免费版,比如:

  • https://www.maxmind.com/en/geoip2-services-and-databases

MaxMind平台提供的IP地址数据库免费付费两种版本。

虽然免费版更新比较慢,但对于精确度不高的项目来说,够用。

MaxMind免费版IP地址数据库叫做GeoLite2,其下载方式如下。

1、注册并登录账号

访问如下地址,注册平台账号;

  • https://www.maxmind.com/en/geolite2/signup

访问如下地址,登录账号;

  • https://www.maxmind.com/en/account/login

登录成功后进入如下页面:

image-20220501165114136

2、下载IP地址数据库

访问左侧的Download Files按钮,进入IP地址数据库下载页面,如下图所示:

image-20220501165246893

我们选择精确到City的免费版mmdb格式的IP地址数据库文件,并下载。

下载完成后是一个压缩包,打开即可看到mmdb格式的数据库文件。

image-20220501165450564

mmdbMaxMind Database,是MaxMind设计的一种用于存储IP地址数据信息的数据库,其采用二分查找树来加速IP信息的查询。

二、IP地址数据库的简单使用

根据MaxMind的开发文档,该数据库的使用方法很简单,一共分两步:

1、导入依赖包

<dependency><groupId>com.maxmind.geoip2</groupId><artifactId>geoip2</artifactId><version>2.16.1</version>
</dependency>

2、配置并查询

File database = new File("/path/to/maxmind-database.mmdb")// This reader object should be reused across lookups as creation of it is expensive.
// 译:这个reader对象应该在整个查找中重用,因为创建它的成本很高。
DatabaseReader reader = new DatabaseReader.Builder(database).build();// If you want to use caching at the cost of a small (~2MB) memory overhead:
// 译:如果要以较小的内存开销(约2MB)为代价使用缓存,请执行以下操作:
// new DatabaseReader.Builder(file).withCache(new CHMCache()).build();InetAddress ipAddress = InetAddress.getByName("128.101.101.101");CityResponse response = reader.city(ipAddress);Country country = response.getCountry();
System.out.println(country.getIsoCode());

详情:https://dev.maxmind.com/geoip/geolocate-an-ip/databases

三、Spring Boot中使用IP地址库

以下代码只展示关键部分。完整代码详见后文。

1、创建Spring Boot项目

创建完成的Spring Boot项目目录结构,如下图所示。

image-20220501171032241

其中,将下载的IP地址数据库文件,放在resources文件夹中的mmdb目录下。

2、导入依赖

pom.xml文件中,导入如下依赖。

<!-- GeoIp2的依赖 -->
<dependency><groupId>com.maxmind.geoip2</groupId><artifactId>geoip2</artifactId><version>2.16.1</version>
</dependency>

3、创建IP属地信息实体

entity包下,新建一个名为Ip2CityEntity的实体,用来保存查询后的IP属地信息

代码如下,逻辑见注释。

package com.zxdmy.tool.entity;import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;import java.io.Serializable;/*** IP属地信息实体类** @author 拾年之璐* @since 2022/5/1 13:24*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class Ip2CityEntity implements Serializable {private static final long serialVersionUID = 1L;/*** IP地址*/private String ip;/*** 国家名称*/private String country;/*** 省份名称*/private String province;/*** 城市名称*/private String city;/*** 经度*/private Double longitude;/*** 维度*/private Double latitude;/*** 查询耗时*/private String cost;
}

4、创建并实现查询工具类

utils包中,新建名为GeoIPUtils的工具类,实现通过IP查询属地信息功能方法。

详细代码如下所示,具体逻辑见注释。

package com.zxdmy.tool.utils;import com.maxmind.db.CHMCache;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import com.zxdmy.tool.entity.Ip2CityEntity;import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;/*** GeoIP数据库操作工具类** @author 拾年之璐* @since 2022/5/1 12:53*/
public class GeoIPUtils {/*** 数据库文件所在的路径(resources文件内)*/private static final String mmdbPath = "mmdb/GeoLite2-City.mmdb";/*** 设置返回的语言:简体中文*/private static final String CHS = "zh-CN";/*** 读取resources文件中的静态数据库*/private static final InputStream mmdbStream = GeoIPUtils.class.getClassLoader().getResourceAsStream(mmdbPath);/*** 数据库加载器,全局静态,只加载一次*/private static DatabaseReader databaseReader;// 静态代码块,初始化时执行一次static {try {databaseReader = new DatabaseReader.Builder(mmdbStream).withCache(new CHMCache()).build();} catch (IOException e) {e.printStackTrace();}}/*** 通过IP查询地址信息** @param ip IP地址* @return 城市地址信息*/public static Ip2CityEntity getIpInfo(String ip) {Ip2CityEntity ip2CityEntity = new Ip2CityEntity();try {// 获取主机的IP(IP可以是域名)InetAddress inetAddress = InetAddress.getByName(ip);// 通过数据库查询该IP的信息CityResponse response = databaseReader.city(inetAddress);// 解析国家String countryName = response.getCountry().getNames().get(CHS);// 解析二级分支(一般是省份)String provinceName = response.getMostSpecificSubdivision().getNames().get(CHS);// 解析城市String cityName = response.getCity().getNames().get(CHS);// 解析坐标Location location = response.getLocation();// 写入实体ip2CityEntity.setIp(ip).setCountry(countryName).setProvince(provinceName).setCity(cityName)// 经度.setLatitude(location.getLatitude())// 维度.setLongitude(location.getLongitude());} catch (Exception e) {System.out.println(e.getMessage());return null;}return ip2CityEntity;}}

5、调用工具类实现具体业务

接下来就可以在控制类服务类切面等场景中,根据实际业务需求,调用GeoIPUtils工具类中的通过IP查询属地信息静态方法,获取某个IP的属地信息。

下面是一种使用实例。

package com.zxdmy.tool.controller;import com.zxdmy.tool.entity.Ip2CityEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;import static com.zxdmy.tool.utils.GeoIPUtils.getIpInfo;/*** 请求查询的控制器** @author 拾年之璐* @since 2022/5/1 17:19*/
@Controller
public class IPController {/*** 请求的入口** @param ip IP地址* @return 查询结果*/@GetMapping({"query"})@ResponseBodypublic Ip2CityEntity index(@RequestParam(name = "ip", required = false) String ip) {// 请求的开始时间long start = System.currentTimeMillis();// 查询结果Ip2CityEntity ip2CityEntity = getIpInfo(ip);// 判断查询结果if (null != ip2CityEntity) {// 写入查询耗时ip2CityEntity.setCost(System.currentTimeMillis() - start + " ms");}// 返回return ip2CityEntity;}
}

四、结果演示与源码下载

在作者的演示项目中,控制类的实现方法如下图所示,查询返回的是JSON数据

image-20220501192614903

4.1 线上演示

注:线上演示项目不提供长久服务,随时下线。若无法访问,请使用本地演示

直接访问演示项目的主页将查询访问者的IP属地信息

主页连接(点击可访问):

  • http://ip.tool.zxdmy.com

访问结果如下图所示。

image-20220501193041915

如果通过Get方式传入IP参数,则将查询该IP的属地信息

访问格式如下:

  • http://ip.tool.zxdmy.com/?ip=114.44.227.87

访问结果如下图所示。

image-20220501193200039

4.2 本地演示

本地演示前,请先保证本机有JDK 1.8环境。

访问如下链接,即可下载演示项目的jar包

https://download.csdn.net/download/cxh_1231/85259992

使用如下命令运行jar包即可启动项目

java -jar Ip2CityDemo-1.1.jar

详情如下图所示。

image-20220501194214805

关闭该CMD命令行窗口,即结束项目。

4.3 源码下载

请访问如下链接下载。

https://download.csdn.net/download/cxh_1231/85259992

— End —


http://chatgpt.dhexx.cn/article/j9XbZ0hL.shtml

相关文章

php 精准定位到街道,ip地址查询精确到街道_ip查询详细地址带地图

ip地址查询精确的位置方法,我们知道,QQ能够查询到i地址对于的用户的位置,但是有时候因为运营商等原因导致 2.查询非移动网络3G/4G的IP地址;这是因为移动3G/4G网络下所使用的公网IP属于多人共用可以定位到街道级别。 IP定位工具(精准到.下载地址:http://pan.baidu.com/s/1o7…

IP地理位置定位技术原理是什么

IP地理位置定位技术的原理是基于IP地址的网络通信原理和基础上的。它利用IP地址所包含的一些信息&#xff0c;如网络前缀和地址段&#xff0c;以及ISP的IP地址归属地数据库&#xff0c;来推测IP地址所对应的地理位置。 具体来说&#xff0c;IP地址是由32位二进制数字组成的&…

Golang — 根据IP获取地理位置信息

Golang — 根据IP获取地理位置信息 1 介绍1.1 ip2region1.2 geoip2-golang1.3 总结 2 使用2.1 ip2region2.2 geoip2-golang 1 介绍 1 ip2region 2 geoip2-golang 1.1 ip2region ip2region 是一个离线IP地址定位库和IP定位数据管理框架&#xff0c;10微秒级别的查询效率&…

python通过ip获取地理位置等ip信息

作者讲话&#xff1a;本人是一个菜鸟勿喷本文章仅供娱乐。 ps&#xff1a;以后可以线下挑战了&#xff0c;直接顺着网线找到你&#xff01;哈哈哈 查询IP数据网站 使用结果1 ‘http://freeapi.ipip.net/ip’ 中文网站 使用结果2 ‘http://ip-api.com/json/ip’ 外国网站 实…

如何利用IP地址确定地理位置

近年来&#xff0c;基于IP地址的网络应用层出不穷&#xff0c;主要包括定向广告、社交网络、网络安全、网络服务性能优化、用户位置画像等。 互联网用户的物理位置对于很多不同类型的应用是有不同的用处的。以搜索引擎为首等应用通常会使用用户的位置来自定义对用户请求的响应。…

python根据IP查询地理位置

实现了输入ip地址返回该ip对应的信息。 如图&#xff1a;解释如下&#xff1a; 打开百度&#xff0c;输入ip打开调试界面&#xff0c;点击图中3号位置过滤在图中4号框位置输入想要查询的ip&#xff0c;然后点查询依次点击图中5、6&#xff0c;找到timestamp字段&#xff0c;粘…

教你如何使用ip地址进行高精度定位

IP这个概念大部分人都很熟悉了&#xff0c;这里IP的意思不是个人标签&#xff0c;而是IP地址&#xff08;英语&#xff1a;Internet Protocol Address&#xff09;是一种在Internet上的给主机编址的方式&#xff0c;也称为网际协议地址。IP地址是IP协议提供的一种统一的地址格式…

windows访问Ext4磁盘

作者 QQ群&#xff1a;852283276 微信&#xff1a;arm80x86 微信公众号&#xff1a;青儿创客基地 B站&#xff1a;主页 https://space.bilibili.com/208826118 参考 在Windows下读取Ext4分区 推荐一款Windows下读取 Linux文件系统Ext4的最佳软件 Paragon ExtFS api-ms-win-cr…

【Linux】Linux Ext2文件系统

下面以Linux的Ext2为例介绍文件系统的组成。 Ext2采用了分立式目录结构&#xff0c;即一个文件的目录分为目录项和索引节点两个部分。 Ext2的索引节点 在一个实际分立式目录的文件系统中&#xff0c;索引节点&#xff08;inode&#xff09;主要需要两部分内容来支持&#xff…

EXT2文件系统实现原理

目录 一 EXT2文件系统结构概览 2 1.1 EXT2文件系统结构框图 2 1.2 EXT2重要数据结构 3 二 块缓存 6 三 EXT2文件系统挂载 7 3.1 注册ext2文件系统类型 7 3.2 ext2文件系统挂载 7 3.3文件系统操作 9 EXT2文件系统结构概览 1.1 EXT2文…

模拟实现EXT2文件系统

设计EXT2文件系统 实验目的 &#xff08;1&#xff09;掌握文件系统的工作原理 &#xff08;2&#xff09;理解文件系统的主要数据结构 &#xff08;3&#xff09;学习较为复杂的 Linux 下的编程 &#xff08;4&#xff09;了解 EXT2 文件系统的结构 实验内容 设计并实现…

WIN10访问linux分区「ext2fsd」

尝试ext2explore、Paragon ExtFS都不好用&#xff0c;强烈安利ext2fsd&#xff0c;可读写&#xff0c;很强大 转自&#xff1a;https://blog.csdn.net/cruise_h/article/details/12894135 ext2fsd是国人发起的项目&#xff0c;主页 http://www.ext2fsd.com/ 下载&#xff1a;h…

windos读写ext3工具_“ ext2fsd” Windows系统工具,用于读写ext2 / 3/4文件系统

在过去的几天里&#xff0c;我使用定制版本的Bridge Linux来扔Arch Linux. 修改lxdm主题时&#xff0c;我无意间无法进入系统&#xff0c;也无法切换命令行模式&#xff0c;因此我不得不找出Windows系统中是否存在可以读写ext4文件系统的工具. 以前尝试过ext2explore&#xff0…

ext2文件系统

ext2是Linux早期比较流行的文件系统&#xff0c;很多文件系统&#xff08;NTFS、FAT32等&#xff09;的设计都源自于它。只要掌握了ext2文件系统&#xff0c;其他文件系统大同小异。 ext2文件系统的布局如下&#xff1a; 文件系统中存储的最小单位是块&#xff08;Block&#…

文件系统系列专题之 Ext2/3/4

一、Ext概述 EXT是延伸文件系统&#xff08;Extended file system&#xff0c;缩写为 ext或 ext1&#xff09;&#xff0c;也译为扩展文件系统&#xff0c;第 1 个扩展文件系统&#xff08;ext1&#xff09;由 Remy Card 设计&#xff0c;并于 1992 年 4 月引入到 Linux 中。采…

深入理解ext2文件系统

ext&#xff12;文件系统需要考虑哪些因素&#xff1a; 1.最重要的是保证数据的安全性。 2.效率&#xff0c;方便文件的查找读写。 3.文件在磁盘空间占用空间小。 (1)树形目录结构 EXT文件系统采用一个独立的顶级树形目录架构&#xff08;即所有一切都从root根目录开始&…

学习篇 | LINUX 内核的文件系统 -- ext2

引言&#xff1a; 本篇博客中主要讲述的是 LINUX 内核所用的文件系统 —— 第二代扩展文件系统 Ext2&#xff0c;Ext2是数个Linux发行版本的默认文件系统。 百度百科 -- ext2 目录 引言&#xff1a; Ext2 文件系统 磁盘的物理组成 ext2 文件系统的格式 ext2 文件系统目录…

ext2文件系统详解

第一部分磁盘的物理组成 磁盘的基本概念&#xff1a; 扇区为最小的物理存储单位&#xff0c;每个扇区为512字节。 将扇区组成一个圆&#xff0c;那就是柱面&#xff0c;柱面是分区的最小单位。 第一个扇区很重要&#xff0c;里面有硬盘主引导记录&#xff08;Masterbootrecord…

编译原理——证明文法具有二义性

证明一个文法具有二义性我们需要掌握两个知识点。 1.语法分析树 定义很简单&#xff0c;就是把一个句型的推导写成树的形式&#xff0c;这种表示法就叫语法分析树&#xff0c;或者简称为语法树。大概是这个样子的 2.二义性 一个文法存在某个句子对应两棵不同的语法树&…