ip2region 获取ip信息不求人

2023-11-209 min 分享

最近想通过获取用户ip信息来准确的输出欢迎界面,在网上搜了半天接口,就没几个能用的,后来偶然发现了lionsoul2014/ip2region这个开源库,提供了很多语言的绑定,速度也是很快的,通过它所提供的xdb数据库来进行本地查询,快速方便,当然也支持自定义数据库

如何使用

我只用过它NodeJSGo的绑定, 接口调用简单,其中NodeJS已经整合了数据库到npm里,Go版本你需要自行下载作者提供的数据库,放到项目中进行读取,所以这里以Go为例进行演示

首先下载data目录下的ip2region.xdb数据库文件,然后 go get github.com/lionsoul2014/ip2region/binding/golang 获取Go绑定,把数据库文件放到项目中任意位置

import (
	"github.com/lionsoul2014/ip2region/binding/golang/xdb"
	"strings"
	"toolkit-api/utils/cache"
)

type IpInfo struct {
	IpAddr   string `json:"ip_addr"`
	Country  string `json:"country"`
	Region   string `json:"region"`
	Province string `json:"province"`
	City     string `json:"city"`
	ISP      string `json:"isp"`
}

var cacheId = "IPInfo_db_VIndex"

func getCacheVIndex() []byte {
	return cache.Get(cacheId)
}

func setCacheVIndex(data []byte) {
	cache.Set(cacheId, data)
}

func GetIpInfo(ip string) (IpInfo, error) {
	var (
		result IpInfo
		err    error
		dPath  = "./assets/ipinfo_db/ip2region.xdb"
	)
    // 这里对VectorIndex进行了缓存,目的是减小一次IO操作
	vIndex := getCacheVIndex()
	if vIndex == nil {
		vIndex, err = xdb.LoadVectorIndexFromFile(dPath)
		if err != nil {
			return result, err
		}
		setCacheVIndex(vIndex)
	}
	 
	searcher, err := xdb.NewWithVectorIndex(dPath, vIndex)
	if err != nil {
		return result, err
	}
	defer searcher.Close()

	region, err := searcher.SearchByStr(ip)
	if err != nil {
		return result, err
	}
	// 原始数据只是字符串,我们进行处理提取信息
	regionData := strings.Split(region, "|")
	result.IpAddr = ip
	result.Country = notZero(regionData[0])
	result.Region = notZero(regionData[1])
	result.Province = notZero(regionData[2])
	result.City = notZero(regionData[3])
	result.ISP = notZero(regionData[4])
	return result, nil
}

func notZero(s string) string {
	if s == "0" {
		return ""
	}
	return s
}

总结

得益于该库所使用的索引算法,查询性能很出色,所提供的数据库在国内的准确性也很不错,我的ip在很多网站显示的是其他省的,但该库提供的数据库就是正确的地理位置,大家在搭建自己的api toolkit时,不妨试试这个库来实现ip信息获取的功能

评论
正在加载评论组件...