根据ip获取地理位置
主流方案就是通过ip地址数据库实现的 https://blog.csdn.net/2401_84924721/article/details/138709140 网上有很多库实现这个操作的,不一定
根据ip获取地理位置
发布时间:2024-10-20 (2024-10-20)

主流方案就是通过ip地址数据库实现的

https://blog.csdn.net/2401_84924721/article/details/138709140

网上有很多库实现这个操作的,不一定非要用我这个库的

demo

// testdata/10.获取地理位置.go
package main

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

func main() {
  ip2region()
}
func ip2region() {
  var dbPath = "init/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 = "175.0.201.207"
  var tStart = time.Now()
  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查询,都是需要加载数据库

所以我们可以在程序运行的时候去加载,后续查询就去使用这个对象去进行查询

// core/init_ip_searcher.go
package core

import (
  "fai_server/global"
  "github.com/lionsoul2014/ip2region/binding/golang/xdb"
  "github.com/sirupsen/logrus"
)

func InitIpSearcher() {
  var dbPath = "init/ip2region.xdb"
  searcher, err := xdb.NewWithFileOnly(dbPath)
  if err != nil {
    logrus.Fatal(err)
  }
  global.IPSearcher = searcher
}

完整代码

var searcher *xdb.Searcher

//go:embed ip2region.xdb
var addrDB []byte

func InitIPDB() {
	_searcher, err := xdb.NewWithBuffer(addrDB)
	if err != nil {
		logrus.Fatalf("ip地址数据库加载失败 %s", err)
		return
	}
	searcher = _searcher
}

func GetIpAddr(ip string) (addr string) {
	if ipUtils.HasLocalIPAddr(ip) {
		return "内网"
	}

	region, err := searcher.SearchByStr(ip)
	if err != nil {
		logrus.Warnf("错误的ip地址 %s", err)
		return "异常地址"
	}
	_addrList := strings.Split(region, "|")
	if len(_addrList) != 5 {
		// 会有这个情况吗?
		logrus.Warnf("异常的ip地址 %s", ip)
		return "未知地址"
	}
	// _addrList 五个部分
	// 国家  0  省份   市   运营商
	country := _addrList[0]
	province := _addrList[2]
	city := _addrList[3]

	if province != "0" && city != "0" {
		return fmt.Sprintf("%s·%s", province, city)
	}
	if country != "0" && province != "0" {
		return fmt.Sprintf("%s·%s", country, province)
	}
	if country != "0" {
		return country
	}
	return region
}

离线方案一般精度不高,如果对精确度有要求,云厂商是有ip地址获取地理位置的api的

也可以取爬这个网站

https://www.ipshudi.com/127.0.0.1.htm

可以定位到区级别

当然,如果你用api和爬虫方案,不要来一个ip就去查一下,而是自己做一个记录,把那些没查过的ip去查一下

而且通过ip获取地址,这不是核心业务,可以开一个协程异步去搞,查完之后再更新回去就好了

https://www.ipshudi.com/175.0.201.207.htm
https://www.ip138.com/iplookup.php?ip=175.0.201.207&action=2