go 获取IP,根据IP获取地理位置信息

臭大佬 2023-07-30 22:11:18 2520
Go 
简介 go 获取IP,根据IP获取地理位置信息

获取ip

gin框架获取客户端IP

在Gin框架中,你可以使用c.ClientIP()方法来获取客户端的IP地址。该方法返回一个字符串,表示客户端的IP地址。

// 获取客户端IP地址 c 为 *gin.Context
ip := c.ClientIP()

获取公网ip

可以用公开的接口ipify,通过发送HTTP请求来获取当前设备的公网IP地址。

func getPublicIP() (string, error) {
    resp, err := http.Get("https://api.ipify.org")
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    ip, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return string(ip), nil
}

根据ip获取地理位置信息

geoip2-golang 使用

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

注册地址:https://www.maxmind.com/en/geolite2/signup, 除了邮箱外,其他都不需要真实信息。

登录

下载最新的IP地理位置库
登陆后点击 Download Databases 进入下载选择页面

下载库文件

maxmind 提供了六种免费的数据库,有mmdb【推荐】,也有csv格式。选择其中一个下载:

下载解压后都是mmdb数据库类型。

下载geoip2-golang

go get github.com/oschwald/geoip2-golang

示例代码:

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net"
    "net/http"

    "github.com/oschwald/geoip2-golang"
)

func main() {
    geoip()
}

func getPublicIP() (string, error) {
    resp, err := http.Get("https://api.ipify.org")
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    ip, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }

    return string(ip), nil
}

func geoip() {
    db, err := geoip2.Open("./GeoLite2-City.mmdb")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    ipAddr, _ := getPublicIP()
    fmt.Printf("ip: %v\n", ipAddr)
    ip := net.ParseIP(ipAddr)
    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)

    fmt.Println("中文结果")
    fmt.Printf("市: %v\n", record.City.Names["zh-CN"])
    if len(record.Subdivisions) > 0 {
        fmt.Printf("省: %v\n", record.Subdivisions[0].Names["zh-CN"])
    }
    fmt.Printf("国家: %v\n", record.Country.Names["zh-CN"])
    fmt.Printf("ISO国家代码: %v\n", record.Country.IsoCode)
    fmt.Printf("时区: %v\n", record.Location.TimeZone)
    fmt.Printf("坐标: %v, %v\n", record.Location.Latitude, record.Location.Longitude)
}

ip: 117.28.181.81
English subdivision name: Fujian
Russian country name: Китай
ISO country code: CN
Time zone: Asia/Shanghai
Coordinates: 24.4798, 118.0819
中文结果
市: 厦门市
省: 福建省
国家: 中国
ISO国家代码: CN
时区: Asia/Shanghai
坐标: 24.4798, 118.0819

参考:https://blog.csdn.net/Mr_XiMu/article/details/130563632