使用 GeoIP2 获取 IP 的地理位置
1. 准备工作
- 数据库 : 解析 IP 地理位置的的数据库来自 GeoLite2 开源数据库:https://dev.maxmind.com/geoip/geoip2/geolite2/ 。
- C 语言 API : 使用的 API 是 maxmind 官网的开源项目 libmaxminddb, 地址是 https://github.com/maxmind/libmaxminddb 。
准备好这两个就可以了。
2. 敲代码
我使用的操作系统是 CentOS7.1。
2.1 编译 libmaxminddb
把 libmaxminddb 的代码下载下来,随便放在什么地方, 然后解压,进入解压后的目录,执行 bootstrap,configure,make
$ tar xzf libmaxminddb-1.3..tar.gz
$ cd libmaxminddb-1.3.
$ ./bootstrap
$ ./configure
$ make
1.在执行 bootstrap 的时候可能会报错,应该是缺少 autoconf 之类的自动构建工具导致的,到谷歌或者百度查询一下安装即可。
2.在执行 make 命令的时候,也会报错,不过报错信息指向的是 libmaxminddb-1.3.1/t 里面缺少 libtap/tap.h。 https://github.com/pozorvlak/libtap 是 libtap 在 GitHub 上的地址, 其项目首页上的注释是:Testing library for C, implementing the Test Anything Protocol. Written by Nik Clayton.
既然是测试使用的,那么不编译应该也没什么大问题。
3.看 make 命令后的编译记录,可以发现 libmaxminddb.a 静态链接库已经编译好了, 并且放在了 libmaxminddb-1.3.1/src/.libs 目录里面。
[root@fengbo libmaxminddb-1.3.]# ls src/.libs/ -l
total
-rw-r--r--. root root Dec : data-pool.o
-rw-r--r--. root root Dec : libmaxminddb.a
lrwxrwxrwx. root root Dec : libmaxminddb.la -> ../libmaxminddb.la
-rw-r--r--. root root Dec : libmaxminddb.lai
lrwxrwxrwx. root root Dec : libmaxminddb.so -> libmaxminddb.so.0.0.
lrwxrwxrwx. root root Dec : libmaxminddb.so. -> libmaxminddb.so.0.0.
-rwxr-xr-x. root root Dec : libmaxminddb.so.0.0.
-rw-r--r--. root root Dec : maxminddb.o
2.2 编写示例代码
示例代码是从 maxmind 的官方 GitHub 上直接复制下来的。不过我加了几条日志信息。 https://github.com/maxmind/libmaxminddb/blob/master/doc/libmaxminddb.md#example
代码如下:$cat example.c
#include <errno.h>
#include "maxminddb.h"
#include <stdlib.h>
#include <string.h> #define xdebug(fmt, arg...) \
do{\
printf("%s %d : ", __FILE__, __LINE__); \
printf(fmt, ##arg); \
printf("\n"); \
}while() int main(int argc, char **argv)
{
if(argc < ) {
xdebug("Usage : %s dbfilename IP", argv[]);
}
char *filename = argv[];
char *ip_address = argv[]; MMDB_s mmdb;
int status = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb); if (MMDB_SUCCESS != status) {
fprintf(stderr, "\n Can't open %s - %s\n",
filename, MMDB_strerror(status)); if (MMDB_IO_ERROR == status) {
fprintf(stderr, " IO error: %s\n", strerror(errno));
}
exit();
} int gai_error, mmdb_error;
MMDB_lookup_result_s result =
MMDB_lookup_string(&mmdb, ip_address, &gai_error, &mmdb_error); if ( != gai_error) {
fprintf(stderr,
"\n Error from getaddrinfo for %s - %s\n\n",
ip_address, gai_strerror(gai_error));
exit();
} if (MMDB_SUCCESS != mmdb_error) {
fprintf(stderr,
"\n Got an error from libmaxminddb: %s\n\n",
MMDB_strerror(mmdb_error));
exit();
} MMDB_entry_data_list_s *entry_data_list = NULL; int exit_code = ;
if (result.found_entry) {
int status = MMDB_get_entry_data_list(&result.entry,
&entry_data_list); if (MMDB_SUCCESS != status) {
fprintf(
stderr,
"Got an error looking up the entry data - %s\n",
MMDB_strerror(status));
exit_code = ;
goto end;
} if (NULL != entry_data_list) {
MMDB_dump_entry_data_list(stdout, entry_data_list, );
}
} else {
fprintf(
stderr,
"\n No entry for this IP address (%s) was found\n\n",
ip_address);
exit_code = ;
} end:
MMDB_free_entry_data_list(entry_data_list);
MMDB_close(&mmdb);
exit(exit_code);
}
编译我们的示例代码:
把 libmaxminddb 源码中的 libmaxminddb-1.3.1/include/maxminddb_config.h 和 libmaxminddb-1.3.1/include/maxminddb.h 放到 example.c 所在的目录下。 还有 libmaxminddb-1.3.1/src/.libs/libmaxminddb.a 也要放进来。
$ gcc -o example example.c ./libmaxminddb.a
$ ls
example example.c libmaxminddb.a maxminddb_config.h maxminddb.h
2.3 下载 GeoLite2 开源数据库
到网页 https://dev.maxmind.com/geoip/geoip2/geolite2/ 中,下载 GeoLite2 的数据库。
Downloads
| Database | MaxMind DB binary, gzipped | CSV format, zipped |
|---|---|---|
| GeoLite2 City | Download (md5 checksum) | Download (md5 checksum) |
| GeoLite2 Country | Download (md5 checksum) | Download (md5 checksum) |
| GeoLite2 ASN (Autonomous System Number) | Download (md5 checksum) | Download (md5 checksum) |
我下载的是 GeoLite2 City 数据库。解压后的文件如下:
[root@fengbo maxmind]# ls GeoLite2-City_20171205/
COPYRIGHT.txt GeoLite2-City.mmdb LICENSE.txt README.txt
2.4 测试一下这个程序的效果
先拿到一个 IP,比如 www.fengbohello.top 的 IP。
[root@fengbo maxmind]$ ping www.fengbohello.top
PING www.fengbohello.top (139.199.212.133) () bytes of data.
bytes from 139.199.212.133: icmp_seq= ttl= time=41.7 ms
运行一下 example 试试看:
[root@fengbo maxmind]$ ./example GeoLite2-City_20171205/GeoLite2-City.mmdb "139.199.212.133"
{
"city":
{
"geoname_id":
<uint32>
"names":
{
"de":
"Peking" <utf8_string>
"en":
"Beijing" <utf8_string>
"es":
"Pekín" <utf8_string>
"fr":
"Pékin" <utf8_string>
"ja":
"北京市" <utf8_string>
"pt-BR":
"Pequim" <utf8_string>
"ru":
"Пекин" <utf8_string>
"zh-CN":
"北京" <utf8_string>
}
}
"continent":
{
"code":
"AS" <utf8_string>
"geoname_id":
<uint32>
"names":
{
"de":
"Asien" <utf8_string>
"en":
"Asia" <utf8_string>
"es":
"Asia" <utf8_string>
"fr":
"Asie" <utf8_string>
"ja":
"アジア" <utf8_string>
"pt-BR":
"Ásia" <utf8_string>
"ru":
"Азия" <utf8_string>
"zh-CN":
"亚洲" <utf8_string>
}
}
"country":
{
"geoname_id":
<uint32>
"iso_code":
"CN" <utf8_string>
"names":
{
"de":
"China" <utf8_string>
"en":
"China" <utf8_string>
"es":
"China" <utf8_string>
"fr":
"Chine" <utf8_string>
"ja":
"中国" <utf8_string>
"pt-BR":
"China" <utf8_string>
"ru":
"Китай" <utf8_string>
"zh-CN":
"中国" <utf8_string>
}
}
"location":
{
"accuracy_radius":
<uint16>
"latitude":
39.928900 <double>
"longitude":
116.388300 <double>
"time_zone":
"Asia/Shanghai" <utf8_string>
}
"registered_country":
{
"geoname_id":
<uint32>
"iso_code":
"CN" <utf8_string>
"names":
{
"de":
"China" <utf8_string>
"en":
"China" <utf8_string>
"es":
"China" <utf8_string>
"fr":
"Chine" <utf8_string>
"ja":
"中国" <utf8_string>
"pt-BR":
"China" <utf8_string>
"ru":
"Китай" <utf8_string>
"zh-CN":
"中国" <utf8_string>
}
}
"subdivisions":
[
{
"geoname_id":
<uint32>
"iso_code":
"" <utf8_string>
"names":
{
"en":
"Beijing" <utf8_string>
"fr":
"Municipalité de Pékin" <utf8_string>
"zh-CN":
"北京市" <utf8_string>
}
}
]
}
我擦,解析结果居然是北京。我问了十三哥,他说我们的服务器是腾讯云的,当时选择的是深圳机房。
下面是使用不同的厂商得到的结果:
| 厂商 | 地理位置 |
|---|---|
| 百度 | 广东省广州市 腾讯集团 |
| ip.cn | 广东省深圳市 腾讯云 |
| freegeoip.net | China.Beijing |
| 新浪:int.dpool.sina.com.cn | 中国.广东.广州 |
| 淘宝:ip.taobao.com | 中国.华南.广东省.广州市.电信 |
| 腾讯:ip.qq.com | 中国广东省广州市 未知 |
有意思吧,我也不知道该信谁的。
同步发表:https://www.fengbohello.top/archives/ip2location-geolite2
使用 GeoIP2 获取 IP 的地理位置的更多相关文章
- 根据ip地址从第三方接口获取详细的地理位置
最近项目某个功能需要根据ip地址从第三方接口获取详细的地理位置,从网上找了很多例子,主要接口有新浪的,淘宝的,腾讯的.试了淘宝的,如果是数量级小的还可以,如果数量级达到上十万级就速度慢了,会导致系统崩 ...
- PHP获取操作系统、IP、地理位置、浏览器、ISP等信息_PHP类代码
PHP语言.浏览器.操作系统.IP.地理位置.ISP,本PHP类里面有以下几种方法,同时也是用法说明: <?php class class_guest_info{ function GetLan ...
- php获取ip地址所在的地理位置的实现
1,通过腾讯或者新浪提供的接口来获取(新浪和腾讯类似) <?php function getIPLocation($queryIP){ $url = 'http://ip.qq ...
- 使用纯真IP库获取用户端地理位置信息
引言 在一些电商类或者引流类的网站中经常会有获取用户地理位置信息的需求,下面我分享一个用纯真IP库获取用户地理位置信息的方案. 正文 第一步:本文的方案是基于纯真IP库的,所以首先要去下载最新的纯真I ...
- [日志分析]Graylog2进阶之获取Nginx来源IP的地理位置信息
如果你们觉得graylog只是负责日志收集的一个管理工具,那就too young too naive .日志收集只是graylog的最最基础的用法,graylog有很多实用的数据清洗和处理的进阶用法. ...
- 使用navigator.geolocation来获取用户的地理位置信息
使用navigator.geolocation来获取用户的地理位置信息 W3C 中新添加了一个名为 Geolocation的 API 规范,Geoloaction API的作用就是通过浏览器获取用户的 ...
- Linux下Python获取IP地址
<lnmp一键安装包>中需要获取ip地址,有2种情况:如果服务器只有私网地址没有公网地址,这个时候获取的IP(即私网地址)不能用来判断服务器的位置,于是取其网关地址用来判断服务器在国内还是 ...
- PHP语言、浏览器、操作系统、IP、地理位置、ISP
)]; } else { $Isp = 'None'; } return $Isp; }}
- PHP 获取IP地址位置信息「聚合数据API」
聚合数据 提供了[查询IP所属区域]的服务接口,只需要以 GET 请求的方式向 API 传入 IP地址 和 APPKEY 即可获得查询结果. 这里的难点主要在于如何通过PHP获取客户端IP地址,以及如 ...
随机推荐
- fastAdmin进阶
基本知识流程一栏链接 bootstrapTable fastadmin系统配置(符内置规则): fastadmin默认的controller已实现的方法 一张图解析fastadmin的表格: fast ...
- 整合django和bootstrap框架
环境: python版本:2.7.8 django版本:1.7.1 bootstrap版本:3.3.0 首先github上面有两个开源的项目用来整合django和bootstrap. https:// ...
- window下配置SSH连接GitHub、GitHub配置ssh key
window下配置SSH连接GitHub.GitHub配置ssh key 此经验分两部分: 第一部分介绍:在windows下通过msysGit(Git for windows.Git Bash)配 ...
- python + seleinum +phantomjs 设置headers和proxy代理
python + seleinum +phantomjs 设置headers和proxy代理 最近因为工作需要使用selenium+phantomjs无头浏览器,其中遇到了一些坑,记录一下,尤 ...
- HDU 1257 最少拦截系统 【贪心】
<题目链接> 题目大意: 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度 ...
- asp.net core Session的测试使用心得及注意事项
sp.net-core中Session是以中间件的形式注册使用的.不比asp.net中的使用,直接使用Session就行. 首先在.net-core框架中注入Session中间件,首先在Configu ...
- GBT 33200-2016 社会治安综合治理 综治中心建设与管理规范 GBT 31000-2015 社会治安综合治理基础数据规范
阚总发的两个国标的标准文件, 看看里面对于数据和问题的分类等. 我们出统计分析,可以按照标准出各个大类小类的各种指标数据. 结合这几天给潍坊弄的12345的报告, 整理出一个可以结合吴中现有平台数据, ...
- 常用的Lambda表达式
Java 8 引入Lambda表达式,对于Java开发人员来说是一大福利,简化了代码,提高了开发效率. 本文主要讲解日常开发中使用频率比较高的几类Lambda表达式. 集合 Lambda表达式的引入 ...
- Linux下MySQL 安装配置
MySQL 是最流行的关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL所使用的SQL语言是用于访问数据库的最常用标准化语言. MySQL由于其体积小.速度快 ...
- Linux硬盘管理
管理好硬盘/dev/xxynsd SCSI SATA USBhd IDE主分区扩展分区 1-4逻辑分区5以后fdisk -l 硬盘名/分区名fdisk -l /dev/sda 如何给硬盘分区?把500 ...