一、示例
import requestsdef GetPublicIP():rsp = requests.get(f'https://ipinfo.io/ip')return rsp.textprint(GetPublicIP())def GetIPLocation(ip):response = requests.get(f'https://ipinfo.io/{ip}/json')data = response.json()return dataip = '8.8.8.8' # 这是Google的公共DNS IP
print(GetIPLocation(ip))
二、用户端调用
如果在用户端调用,如客户端,app等,可以直接使用 ipinfo.io 的接口。因为 ipinfo.io 提供了免费套餐,一个帐户可以有 50,000次每个月。
就算不注册帐户,也有一定次数的免费额度。
It’s also possible to use the API without authentication in a more limited capacity.
# With Basic Auth
$ curl -u 048a85f6a2a791: ipinfo.io# With Bearer token
$ curl -H "Authorization: Bearer 048a85f6a2a791" ipinfo.io# With token query parameter
$ curl ipinfo.io?token=048a85f6a2a791
三、服务端调用
可以注册一批帐户池,来扩大免费套餐的限制
// 管理 API 令牌的轮询及统计
type TokenManager struct {tokens []string // 50,000 requests per-month for each tokencallCounts map[string]int // 统计次数index int // token 数组的索引mu sync.Mutex
}func NewTokenManager(tokens []string) *TokenManager {callCounts := make(map[string]int)for _, token := range tokens {callCounts[token] = 0}return &TokenManager{tokens: tokens,index: 0,callCounts: callCounts,}
}// 轮询获取下一个令牌并更新调用次数
func (tm *TokenManager) GetNextToken() string {tm.mu.Lock()defer tm.mu.Unlock()token := tm.tokens[tm.index]tm.callCounts[token]++tm.index = (tm.index + 1) % len(tm.tokens)return token
}// GetCallCounts 返回每个令牌的调用次数
func (tm *TokenManager) GetCallCounts() map[string]int {tm.mu.Lock()defer tm.mu.Unlock()counts := make(map[string]int)for token, count := range tm.callCounts {counts[token] = count}return counts
}var gTokenMgr = NewTokenManager([]string{"......8978....","......7e70....","......7745....","......f6a2....",
})func GetIpLocation(ctx iris.Context) {defer func() {if r := recover(); r != nil {util.GLog().Error(r)}}()remoteIP := ctx.RemoteAddr() // 获取 IPip := strings.Split(remoteIP, ":")[0] // 去掉端口号url := "https://ipinfo.io/" + ip + "/json?token=" + gTokenMgr.GetNextToken()rsp, err := http.Get(url)if err != nil {msg := "Error fetching IP info"util.GLog().Error(ip, msg)ctx.StatusCode(http.StatusInternalServerError)ctx.Text(msg)return}defer rsp.Body.Close()body, err := io.ReadAll(rsp.Body)if err != nil {msg := "Error reading response body"util.GLog().Error(ip, msg)ctx.StatusCode(http.StatusInternalServerError)ctx.Text(msg)return}util.GLog().Info(string(body))ctx.Text(string(body))
}func Dump(ctx iris.Context) {callCounts := gTokenMgr.GetCallCounts()ctx.JSON(callCounts)
}