py_ip.jpg

Python网络开发简单的IP城市定位WebAPI

  • 之前学习Python,已经学会了使用IP和查询所在国家和城市,使用 ipip-ipdb 库和github上分享的IP地址库还是挺简单的。
  • 如果你还想了解 ipip-ipdb 库使用,可以等下再看 链接 《Python脚本: 统计访问Nginx的前100个IP和查询所在国家和城市》

WebAPI演示: https://lyvba.com/ip/

getip.png

现在来说明 Python网络开发 的部署,部署成功能如下图,输入 curl 命令获得正确的IP定位

ip.png

首先第一步,安装 "Flaskipip-ipdb 两个所需库

  • 如果你电脑或者服务器 已经安装有 Python3,只需下面一行命令就能安装

    pip3  install Flask  ipip-ipdb

111.png

  • 我实际是部署在博客服务器上,所以我使用 Docker 容器方式部署,这样的好处是不会把服务器搞崩溃和删除清理也很简单

如果你也使用 Docker Python3 方式测试,可以试用我的容器方法

# 部署 Docker Python3 容器在后台运行
docker run -d  -p 5000:5000 --restart=always   \r
    -v /app:/app  --name python3 \r
    hongwenjun/python3  \r
    python3 -m http.server 8000

# 进入容器 安装 Flask  ipip-ipdb库
docker exec -it python3 bash
pip3  install Flask  ipip-ipdb

接下第二步,下载 QQ纯真IP地址库,和 app.py 的源码

app.png

cd /app
wget https://cdn.jsdelivr.net/npm/qqwry.ipdb/qqwry.ipdb
wget https://raw.githubusercontent.com/hongwenjun/srgb/master/python/app.py

部署已经完成,第三步只要把 IP城市定位WebAPI 运行起来就可以了

tmux.png

  • 使用 tmux 把 flask run 程序保持到后台运行

    tmux -u
    flask run --host=0.0.0.0

使用 curl 测试 WebAPI 能够正确使用

# curl 172.17.0.3:5000
<p>Hello, World!</p>

# curl 172.17.0.3:5000/ip/8.8.8.8
8.8.8.8 @美国加利福尼亚州圣克拉拉

接下就使用 nginx 反向代理端口配置,使用效果还不错

location /ip/ {
    proxy_pass http://172.17.0.3:5000/ip/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Protocol $scheme;
    proxy_set_header X-Forwarded-Host $http_host;


    proxy_buffering off;
}

app.py 源码初始版 最新版

import  ipdb, ipaddress
from flask import Flask
# export FLASK_ENV=development
# flask run --host=0.0.0.0

db = ipdb.BaseStation("qqwry.ipdb")
app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

@app.route('/ip/<ipaddr>')
def show_ip_profile(ipaddr):
    ip = ipaddr
    try:
        ipaddress.ip_address(ip).is_global
        # print(ip, db.find(ip, "CN"))
        city = db.find(ip, "CN")
        ipaddr =  ip + " @" + city[0] + city[1] + city[2] + "
"
    except:
        pass
    return ipaddr

app.py 源码另一种版本

import ipdb, ipaddress
from flask import Flask, request, jsonify

db = ipdb.BaseStation("qqwry.ipdb")
app = Flask(__name__)

@app.route("/ip/")
@app.route("/ip/<ipaddr>")
def show_ip(ipaddr=None):
    # ip 地址为空获得浏览器客户端IP
    if ipaddr is None:
        ip = request.remote_addr
        try:
            _ip = request.headers["X-Real-IP"]
            if _ip is not None:
                ip = _ip
        except Exception as e:
            print(e)
    else:
        ip = ipaddr

    # ip地址 从纯真IP数据库 搜索城市定位
    try:
        ipaddress.ip_address(ip).is_global
        city = db.find(ip, "CN")
        ipaddr = ip + " @" + city[0] + city[1] + city[2] + city[3] + "
"
    except Exception as e:
        print(e)

    return ipaddr

# export FLASK_ENV=development   # 调试模式: 修改代码不用重启服务
# flask run --host=0.0.0.0       # 监听所有公开的 IP

app.py 源码 支持域名查 IP定位

import ipdb, ipaddress
from flask import Flask, request, jsonify
from socket import gethostbyname

db = ipdb.BaseStation("qqwry.ipdb")
app = Flask(__name__)

def iplocated(ip):
    city = db.find(ip, "CN")
    return ip + " @" + city[0] + city[1] + city[2] + city[3] + "
"

@app.route("/ip/")
@app.route("/ip/<ipaddr>")
def show_ip(ipaddr=None):
    # ip 地址为空获得浏览器客户端IP
    if ipaddr is None:
        ip = request.remote_addr
        try:
            _ip = request.headers["X-Real-IP"]
            if _ip is not None:
                ip = _ip
        except Exception as e:
            print(e)
    else:
        ip = ipaddr

    # ip地址 从纯真IP数据库 搜索城市定位
    try:
        ipaddress.ip_address(ip).is_global
        ipaddr = iplocated(ip)
    except:
        try:
            ip = gethostbyname(ip)     # 域名反解析得到的IP
            ipaddr = iplocated(ip)
        except Exception as e:
            print(e)

    return ipaddr

# export FLASK_ENV=development   # 调试模式: 修改代码不用重启服务
# flask run --host=0.0.0.0       # 监听所有公开的 IP
分类: 学习编程

0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注