本文介绍: Golang — 根据IP获取地理位置信息

1 介绍

1 ip2region
2 geoip2-golang

1.1 ip2region

ip2region 是一个离线IP地址定位库和IP定位数据管理框架,10微秒级别的查询效率,提供了众多主流编程语言的 xdb 数据生成和查询客户端实现。

特点:

  1. 是一个开源的IP地理位置库。
  2. 标准化的数据格式
    每个 ip 数据段的 region 信息都固定了格式:国家|区域|省份|城市|ISP,只有中国的数据绝大部分精确到了城市,其他国家部分数据只能定位到国家,后前的选项全部是0。
  3. 数据去重和压缩
  4. 极速查询响应
    即使是完全基于 xdb 文件的查询,单次查询响应时间在十微秒级别。
  5. IP 数据管理框架

缺点:
ip2region 重点在于 研究 IP 数据的存储和快速查询的实现,并没有原始 IP 数据的支撑,本项目不保证及时的数据更新,暂时也不会有商用版本。

1.2 geoip2-golang

geoip2-golang只是一个使用示例,它所需的IP地理信息库是基于MaxMind提供的 GeoLite2GeoIP2 数据库。

特点:

  1. maxmind提供了免费的可在本地部署的geo-ip数据库(GeoLite2)(mmdb以及csv格式),和geo-ip查询api服务。
  2. 支持ipv4和ipv6的地理信息查询,以及ASN数据库(ip-运营商信息查询)
  3. 免费的数据库更新周期为两周一次,需要付费才能得到最快的更新速度。

1.3 总结

推荐优先使用 geoip2-golang,其次是ip2region,如果需要更加精确的话,建议选择商用的。

2 使用

2.1 ip2region

  1. 下载ip地址库
    到github:https://github.com/lionsoul2014/ip2region下载代码。

  2. ip2region的库
    data下的ip2region.xdb
    在这里插入图片描述

  3. 使用

package main

import (
	"fmt"
	"github.com/lionsoul2014/ip2region/binding/golang/xdb"
	"net"
	"time"
)

func main() {
	ip2region()
}
func ip2region() {
	var dbPath = "iputil/ip2region/ip2region.xdb"
	searcher, err := xdb.NewWithFileOnly(dbPath)
	if err != nil {
		fmt.Printf("failed to create searcher: %sn", err.Error())
		return
	}

	defer searcher.Close()
	var ip = "115.223.9.122"
	var tStart = time.Now()
	ips, err := net.LookupIP("www.github.com")
	ipres := ips[0].String()
	fmt.Printf("域名的ip:%sn", ipres)
	region, err := searcher.SearchByStr(ip)
	if err != nil {
		fmt.Printf("failed to SearchIP(%s): %sn", ip, err)
		return
	}
	fmt.Printf("{region: %s, took: %s}nn", region, time.Since(tStart))
	// 备注:并发使用,每个 goroutine 需要创建一个独立的 searcher 对象。
}

结果:

域名的ip:20.205.243.166
{region: 中国|0|浙江省|温州市|电信, took: 70.8846ms}

2.2 geoip2-golang

geoip2-golang只是一个使用示例,它所需的IP地理信息库是基于MaxMind提供的 GeoLite2GeoIP2 数据库。所以需要去MAXMID官网注册账号,然后才能下载最新的IP地理位置库

  1. 注册
    地址:https://www.maxmind.com/en/geolite2/signup,除了邮箱外,其他都不需要真实信息。
  2. 登录
  3. 下载最新的IP地理位置库
    登陆后点击 Download Databases进入下载选择页面
    在这里插入图片描述
  4. 下载库文件
    maxmind提供了六种免费的数据库,有mmdb【推荐】,也有csv格式。你也可以全部下载下来看看。

ASN数据库
从图中可以看到有些数据库的标题后面写着“ASN”三个字母,这个ASN的指的就是ip-运营商信息的数据库。

mmdb数据库
mmdbmaxmind自己的一种二进制数据库格式,它提供较快的ip查询速度。

这里我们只下载不是CSV格式的库文件即可,即只下载红色圈起来的,右侧是下载按钮。

注意MAXMIND会记录下载,所以不要反复下载,以免被禁。
在这里插入图片描述

  1. 库文件
  • GeoLite2-ASN_20230505.tar.gz
  • GeoLite2-City_20230505.tar.gz
  • GeoLite2-Country_20230505.tar.gz

解压后都是mmdb数据库类型,具体差别自己测试吧。

  1. 使用
  • 下载geoip2-golang
go get github.com/oschwald/geoip2-golang

代码示例:

package main

import (
	"fmt"
	"github.com/lionsoul2014/ip2region/binding/golang/xdb"
	"github.com/oschwald/geoip2-golang"
	"log"
	"net"
	"time"
)

func main() {
	ip2region()
	geoip()
}
func ip2region() {
	var dbPath = "iputil/ip2region/ip2region.xdb"
	searcher, err := xdb.NewWithFileOnly(dbPath)
	if err != nil {
		fmt.Printf("failed to create searcher: %sn", err.Error())
		return
	}

	defer searcher.Close()
	var ip = "115.223.9.122"
	var tStart = time.Now()
	ips, err := net.LookupIP("www.github.com")
	ipres := ips[0].String()
	fmt.Printf("域名的ip:%sn", ipres)
	region, err := searcher.SearchByStr(ip)
	if err != nil {
		fmt.Printf("failed to SearchIP(%s): %sn", ip, err)
		return
	}
	fmt.Printf("{region: %s, took: %s}nn", region, time.Since(tStart))
	// 备注:并发使用,每个 goroutine 需要创建一个独立的 searcher 对象。
}

func geoip() {
	db, err := geoip2.Open("iputil/geolite2/GeoLite2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	// If you are using strings that may be invalid, check that ip is not nil
	//ip := net.ParseIP("81.2.69.142")
	ip := net.ParseIP("115.192.211.101")
	record, err := db.City(ip)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Portuguese (BR) city name: %vn", record.City.Names["pt-BR"])
	if len(record.Subdivisions) > 0 {
		fmt.Printf("English subdivision name: %vn", record.Subdivisions[0].Names["en"])
	}
	fmt.Printf("Russian country name: %vn", record.Country.Names["ru"])
	fmt.Printf("ISO country code: %vn", record.Country.IsoCode)
	fmt.Printf("Time zone: %vn", record.Location.TimeZone)
	fmt.Printf("Coordinates: %v, %vn", record.Location.Latitude, record.Location.Longitude)
	// Output:
	// Portuguese (BR) city name: Londres
	// English subdivision name: England
	// Russian country name: Великобритания
	// ISO country code: GB
	// Time zone: Europe/London
	// Coordinates: 51.5142, -0.0931

	fmt.Println("中文结果")
	fmt.Printf("Portuguese (BR) city name: %vn", record.City.Names["zh-CN"])
	if len(record.Subdivisions) > 0 {
		fmt.Printf("English subdivision name: %vn", record.Subdivisions[0].Names["zh-CN"])
	}
	fmt.Printf("Russian country name: %vn", record.Country.Names["zh-CN"])
	fmt.Printf("ISO country code: %vn", record.Country.IsoCode)
	fmt.Printf("Time zone: %vn", record.Location.TimeZone)
	fmt.Printf("Coordinates: %v, %vn", record.Location.Latitude, record.Location.Longitude)
}

结果:

Portuguese (BR) city name: Hangzhou
English subdivision name: Zhejiang
Russian country name: Китай
ISO country code: CN
Time zone: Asia/Shanghai
Coordinates: 30.2994, 120.1612
中文结果
Portuguese (BR) city name: 杭州
English subdivision name: 浙江省
Russian country name: 中国
ISO country code: CN
Time zone: Asia/Shanghai
Coordinates: 30.2994, 120.1612
  1. 将输出结果改为中文
    只需要将Names[“en”]更改为Names[“zh-CN”]即可显示中文。

原文地址:https://blog.csdn.net/Mr_XiMu/article/details/130563632

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_51447.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注