1 ip2region
2 geoip2-golang
1.1 ip2region
ip2region
特点:
- 是一个开源的IP地理位置库。
- 标准化的数据格式
每个 ip 数据段的 region 信息都固定了格式:国家|区域|省份|城市|ISP,只有中国的数据绝大部分精确到了城市,其他国家部分数据只能定位到国家,后前的选项全部是0。 - 数据去重和压缩
- 极速查询响应
即使是完全基于 xdb 文件的查询,单次查询响应时间在十微秒级别。 - IP 数据管理框架
ip2region研究 IP 数据的存储和快速查询的实现本项目不保证及时的数据更新
1.2 geoip2-golang
geoip2-golangMaxMindGeoLite2GeoIP2
特点:
maxmind更新周期为两周一次
1.3 总结
geoip2-golangip2region
2 使用
2.1 ip2region
ip2regiondataip2region.xdb
package mainimport ("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: %s\n", 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:%s\n", ipres)region, err := searcher.SearchByStr(ip)if err != nil {fmt.Printf("failed to SearchIP(%s): %s\n", ip, err)return}fmt.Printf("{region: %s, took: %s}\n\n", region, time.Since(tStart))// 备注:并发使用,每个 goroutine 需要创建一个独立的 searcher 对象。
}
结果:
域名的ip:20.205.243.166
{region: 中国|0|浙江省|温州市|电信, took: 70.8846ms}
2.2 geoip2-golang
geoip2-golangMaxMindGeoLite2GeoIP2MAXMIDIP地理位置库
IP地理位置库mmdbcsv
ASN数据库
从图中可以看到有些数据库的标题后面写着“ASN”三个字母,这个ASN的指的就是ip-运营商信息的数据库。
mmdbmaxmind
CSV格式
MAXMIND
- 库文件
- GeoLite2-ASN_20230505.tar.gz
- GeoLite2-City_20230505.tar.gz
- GeoLite2-Country_20230505.tar.gz
解压后都是mmdb数据库类型,具体差别自己测试吧。
- 使用
geoip2-golang
go get github.com/oschwald/geoip2-golang
代码示例:
package mainimport ("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: %s\n", 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:%s\n", ipres)region, err := searcher.SearchByStr(ip)if err != nil {fmt.Printf("failed to SearchIP(%s): %s\n", ip, err)return}fmt.Printf("{region: %s, took: %s}\n\n", 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: %v\n", record.City.Names["pt-BR"])if len(record.Subdivisions) > 0 {fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names["en"])}fmt.Printf("Russian country name: %v\n", record.Country.Names["ru"])fmt.Printf("ISO country code: %v\n", record.Country.IsoCode)fmt.Printf("Time zone: %v\n", record.Location.TimeZone)fmt.Printf("Coordinates: %v, %v\n", 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.0931fmt.Println("中文结果")fmt.Printf("Portuguese (BR) city name: %v\n", record.City.Names["zh-CN"])if len(record.Subdivisions) > 0 {fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names["zh-CN"])}fmt.Printf("Russian country name: %v\n", record.Country.Names["zh-CN"])fmt.Printf("ISO country code: %v\n", record.Country.IsoCode)fmt.Printf("Time zone: %v\n", record.Location.TimeZone)fmt.Printf("Coordinates: %v, %v\n", 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
- 将输出结果改为中文
只需要将Names[“en”]更改为Names[“zh-CN”]即可显示中文。