私有化部署自己的IP地理位置数据库 2022-3-14

需求

各类公网的数据库,都限制了请求频次,有时候,自己需要批量的查询需求,得不到满足,于是,有了,自己掌握数据,自己搭建可供查询服务的需求

清单

1、数据库

2、基于Flask的API接口模块

配置清单

1、主程序文件

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Dasmz
# 2022-3-14

import datetime
import time
import flask
import ipaddress
import sqlite3

import ISO_3166_1

myDB = '这里是数据库的文件路径'

def getNow():
    return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    

def IPIsValid(vIPv4):
    try:
        vBLACKIPs = ['8.8.8.8', '1.1.1.1','0.0.0.0','255.255.255.255','192.168.1.1','1.0.0.0','6.6.6.6']
        if ipaddress.IPv4Address(vIPv4) != ipaddress.IPv4Address('127.0.0.1') and vIPv4 not in vBLACKIPs:
            return 'Y'
        else:
            return 'N'
    except Exception as e:
        print(e)
        print('Tracker.Error.82aE9F6a40E38E40.IPIsValid')
        return 'N' 

def getIPNetwork(aIPv4):
    x = aIPv4.split('.')
    x[3] = '0'
    return '.'.join(x)

def getIPRangeNetwork(aIPv4):
    x = aIPv4.split('.')
    return ["%s.%s.%d.0" % (x[0],x[1],i) for i in range(0,256)]

def runSelectSQL(aDB, aSQL):
    '''
    RETURN LIST
    '''
    try:
        conn = sqlite3.connect(aDB)
        csr = conn.cursor()
        csr.execute(aSQL)
        vData = csr.fetchall()
        conn.close()
        return vData     
    except Exception as e:
        print("Tracker.Error.82aE9F6a40E38E40.runSelectSQL")
        print(e)
        return []
    finally:
        conn.close() 

def procedureIP(aIPv4):
    try:
        vIP  = getIPNetwork(aIPv4 = aIPv4)    # 202.23.99.44 -> 202.23.99.0
        vSQL = "select location from ip where ip = '%s';" % vIP
        print(" + SQL: %s" % vSQL)
        vData = runSelectSQL(aDB = myDB, aSQL = vSQL)
        if vData[0][0]:
            if vData[0][0].startswith('CN-'):
                return vData[0][0].split()[0].replace('CN-','')
            else:
                return getCountryZHName(vData[0][0].split()[0])
        else:
            return '404'
    except Exception as e:
        print("Tracker.Error.aCCbfEAaCcfEBCD7.procedureIP")
        print(e)
        print("\n('%s','NotFoundTag')," % (vIP))
        return '404'

def procedureIP_full(aIPv4):
    try:
        vIP  = getIPNetwork(aIPv4 = aIPv4)    # 202.23.99.44 -> 202.23.99.0
        vSQL = "select location from ip where ip = '%s';" % vIP
        print(" + SQL: %s" % vSQL)
        vData = runSelectSQL(aDB = myDB, aSQL = vSQL)
        if vData[0][0]:
            return vData[0][0]
        else:
            return '404'
    except Exception as e:
        print("Tracker.Error.aCCbfEAaCcfEBCD7.procedureIP")
        print(e)
        print("\n('%s','NotFoundTag')," % (vIP))
        return '404'


def getCountryZHName(char2code):
    try:
        return ISO_3166_1.iso_3166_1.get(char2code)
    except Exception as e:
        print("Tracker.Error.D1b808762AC4dCAA.getCountryZHName")
        print(e)
        return '未知-%s' % char2code




app = flask.Flask(__name__)

@app.route('/ipservice', methods=['GET'])
def ipservice():
    try:
        aIP = flask.request.args.get("ip")
        aIPOK = IPIsValid(vIPv4 = aIP)
        if aIPOK == 'Y':
            print("\n\n\n + Target IP Address: %s" % aIP)
            vData = procedureIP(aIPv4 = aIP)
            return vData
        else:
            return '404'
    except Exception as e:
        print("Tracker.Error.67daA1cB92BBBafc.ipmsg")
        print(e)
        return '404'

@app.route('/ipservicefull', methods=['GET'])
def ipservicefull():
    try:
        aIP = flask.request.args.get("ip")
        aIPOK = IPIsValid(vIPv4 = aIP)
        if aIPOK == 'Y':
            print("\n\n\n + Target IP Address: %s" % aIP)
            vData = procedureIP_full(aIPv4 = aIP)
            return vData
        else:
            return '404'
    except Exception as e:
        print("Tracker.Error.67daA1cB92BBBafc.ipmsg")
        print(e)
        return '404'


if __name__ == "__main__":
    app.run(host='0.0.0.0',port=18040)
ISO标准国家地区代码文件 ISO_3166_1.py 主要就是一个对照关系的字典,增加了一个UK英国,自己习惯用UK表示英国,这个GB才是其非标准定义。

iso_3166_1 = {
"AX":"奥兰群岛",
"AL":"阿尔巴尼亚",
"DZ":"阿尔及利亚",
"AS":"美属萨摩亚",
"AD":"安道尔",
"AO":"安哥拉",
"AI":"安圭拉",
"AQ":"南极洲",
"AG":"安提瓜和巴布达",
"AR":"阿根廷",
"AM":"亚美尼亚",
"AW":"阿鲁巴",
"AU":"澳大利亚",
"AT":"奥地利",
"AZ":"阿塞拜疆",
"BS":"巴哈马",
"BH":"巴林",
"BD":"孟加拉国",
"BB":"巴巴多斯",
"BY":"白俄罗斯",
"BE":"比利时",
"BZ":"伯利兹",
"BJ":"贝宁",
"BM":"百慕大",
"BT":"不丹",
"BO":"玻利维亚",
"BA":"波黑",
"BW":"博茨瓦纳",
"BV":"布维岛",
"BR":"巴西",
"IO":"英属印度洋领地",
"BN":"文莱",
"BG":"保加利亚",
"BF":"布基纳法索",
"BI":"布隆迪",
"KH":"柬埔寨",
"CM":"喀麦隆",
"CA":"加拿大",
"CV":"佛得角",
"KY":"开曼群岛",
"CF":"中非",
"TD":"乍得",
"CL":"智利",
"CN":"中国",
"CX":"圣诞岛",
"CC":"科科斯群岛",
"CO":"哥伦比亚",
"KM":"科摩罗",
"CG":"刚果布",
"CD":"刚果金",
"CK":"库克群岛",
"CR":"哥斯达黎加",
"CI":"科特迪瓦",
"HR":"克罗地亚",
"CU":"古巴",
"CY":"塞浦路斯",
"CZ":"捷克",
"DK":"丹麦",
"DJ":"吉布提",
"DM":"多米尼克",
"DO":"多米尼加",
"EC":"厄瓜多尔",
"EG":"埃及",
"SV":"萨尔瓦多",
"GQ":"赤道几内亚",
"ER":"厄立特里亚",
"EE":"爱沙尼亚",
"ET":"埃塞俄比亚",
"FK":"福克兰群岛",
"FO":"法罗群岛",
"FJ":"斐济",
"FI":"芬兰",
"FR":"法国",
"GF":"法属圭亚那",
"PF":"法属波利尼西亚",
"TF":"法属南部领地",
"GA":"加蓬",
"GM":"冈比亚",
"GE":"格鲁吉亚",
"DE":"德国",
"GH":"加纳",
"GI":"直布罗陀",
"GR":"希腊",
"GL":"格陵兰",
"GD":"格林纳达",
"GP":"瓜德罗普",
"GU":"关岛",
"GT":"危地马拉",
"GG":"格恩西岛",
"GN":"几内亚",
"GW":"几内亚比绍",
"GY":"圭亚那",
"HT":"海地",
"HM":"赫德岛和麦克唐纳岛",
"VA":"梵蒂冈",
"HN":"洪都拉斯",
"HK":"中国香港",
"HU":"匈牙利",
"IS":"冰岛",
"IN":"印度",
"ID":"印度尼西亚",
"IR":"伊朗",
"IQ":"伊拉克",
"IE":"爱尔兰",
"IM":"英国属地曼岛",
"IL":"以色列",
"IT":"意大利",
"JM":"牙买加",
"JP":"日本",
"JE":"泽西岛",
"JO":"约旦",
"KZ":"哈萨克斯坦",
"KE":"肯尼亚",
"KI":"基里巴斯",
"KP":"朝鲜",
"KR":"韩国",
"KW":"科威特",
"KG":"吉尔吉斯斯坦",
"LA":"老挝",
"LV":"拉脱维亚",
"LB":"黎巴嫩",
"LS":"莱索托",
"LR":"利比里亚",
"LY":"利比亚",
"LI":"列支敦士登",
"LT":"立陶宛",
"LU":"卢森堡",
"MO":"中国澳门",
"MK":"前南马其顿",
"MG":"马达加斯加",
"MW":"马拉维",
"MY":"马来西亚",
"MV":"马尔代夫",
"ML":"马里",
"MT":"马耳他",
"MH":"马绍尔群岛",
"MQ":"马提尼克",
"MR":"毛利塔尼亚",
"MU":"毛里求斯",
"YT":"马约特",
"MX":"墨西哥",
"FM":"密克罗尼西亚联邦",
"MD":"摩尔多瓦",
"MC":"摩纳哥",
"MN":"蒙古",
"ME":"黑山",
"MS":"蒙特塞拉特",
"MA":"摩洛哥",
"MZ":"莫桑比克",
"MM":"缅甸",
"NA":"纳米比亚",
"NR":"瑙鲁",
"NP":"尼泊尔",
"NL":"荷兰",
"AN":"荷属安的列斯",
"NC":"新喀里多尼亚",
"NZ":"新西兰",
"NI":"尼加拉瓜",
"NE":"尼日尔",
"NG":"尼日利亚",
"NU":"纽埃",
"NF":"诺福克岛",
"MP":"北马里亚纳",
"NO":"挪威",
"OM":"阿曼",
"PK":"巴基斯坦",
"PW":"帕劳",
"PS":"巴勒斯坦",
"PA":"巴拿马",
"PG":"巴布亚新几内亚",
"PY":"巴拉圭",
"PE":"秘鲁",
"PH":"菲律宾",
"PN":"皮特凯恩",
"PL":"波兰",
"PT":"葡萄牙",
"PR":"波多黎各",
"QA":"卡塔尔",
"RE":"留尼汪",
"RO":"罗马尼亚",
"RU":"俄罗斯联邦",
"RW":"卢旺达",
"SH":"圣赫勒拿",
"KN":"圣基茨和尼维斯",
"LC":"圣卢西亚",
"PM":"圣皮埃尔和密克隆",
"VC":"圣文森特和格林纳丁斯",
"WS":"萨摩亚",
"SM":"圣马力诺",
"ST":"圣多美和普林西比",
"SA":"沙特阿拉伯",
"SN":"塞内加尔",
"RS":"塞尔维亚",
"SC":"塞舌尔",
"SL":"塞拉利昂",
"SG":"新加坡",
"SK":"斯洛伐克",
"SI":"斯洛文尼亚",
"SB":"所罗门群岛",
"SO":"索马里",
"ZA":"南非",
"GS":"南乔治亚岛和南桑德韦奇岛",
"ES":"西班牙",
"LK":"斯里兰卡",
"SD":"苏丹",
"SR":"苏里南",
"SJ":"斯瓦尔巴岛和扬马延岛",
"SZ":"斯威士兰",
"SE":"瑞典",
"CH":"瑞士",
"SY":"叙利亚",
"TW":"台湾",
"TJ":"塔吉克斯坦",
"TZ":"坦桑尼亚",
"TH":"泰国",
"TL":"东帝汶",
"TG":"多哥",
"TK":"托克劳",
"TO":"汤加",
"TT":"特立尼达和多巴哥",
"TN":"突尼斯",
"TR":"土耳其",
"TM":"土库曼斯坦",
"TC":"特克斯和凯科斯群岛",
"TV":"图瓦卢",
"UG":"乌干达",
"UA":"乌克兰",
"AE":"阿联酋",
"GB":"英国",
"US":"美国",
"UM":"美国本土外小岛屿",
"UY":"乌拉圭",
"UZ":"乌兹别克斯坦",
"VU":"瓦努阿图",
"VE":"委内瑞拉",
"VN":"越南",
"VG":"英属维尔京群岛",
"VI":"美属维尔京群岛",
"WF":"瓦利斯和富图纳",
"EH":"西撒哈拉",
"YE":"也门",
"YU":"南斯拉夫",
"ZM":"赞比亚",
"ZW":"津巴布韦",
"UK":"英国",
}

自用的API地址,不公开地址。

发表回复

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