Update main.py
Browse files
main.py
CHANGED
|
@@ -8,26 +8,36 @@ import sys
|
|
| 8 |
import os
|
| 9 |
from logging.handlers import RotatingFileHandler
|
| 10 |
|
|
|
|
| 11 |
LOG_FILE = os.path.join('/code', 'ip_query.log')
|
| 12 |
|
|
|
|
| 13 |
try:
|
|
|
|
| 14 |
formatter = logging.Formatter('%(message)s')
|
|
|
|
|
|
|
| 15 |
log_handler = RotatingFileHandler(
|
| 16 |
LOG_FILE,
|
| 17 |
-
maxBytes=10*1024*1024,
|
| 18 |
backupCount=5,
|
| 19 |
encoding='utf-8'
|
| 20 |
)
|
| 21 |
log_handler.setFormatter(formatter)
|
|
|
|
|
|
|
| 22 |
logger = logging.getLogger('ip_query')
|
| 23 |
logger.setLevel(logging.INFO)
|
| 24 |
logger.addHandler(log_handler)
|
|
|
|
|
|
|
| 25 |
startup_log = {
|
| 26 |
"时间": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
| 27 |
"事件": "系统启动",
|
| 28 |
"状态": "成功"
|
| 29 |
}
|
| 30 |
logger.info(json.dumps(startup_log, ensure_ascii=False))
|
|
|
|
| 31 |
except Exception as e:
|
| 32 |
print(f"日志初始化失败: {e}")
|
| 33 |
sys.exit(1)
|
|
@@ -35,42 +45,67 @@ except Exception as e:
|
|
| 35 |
city_reader = maxminddb.open_database('GeoLite2-City.mmdb')
|
| 36 |
asn_reader = maxminddb.open_database('GeoLite2-ASN.mmdb')
|
| 37 |
cn_reader = maxminddb.open_database('GeoCN.mmdb')
|
| 38 |
-
lang = ["zh-CN",
|
| 39 |
asn_map = {
|
| 40 |
-
9812:
|
| 41 |
-
9389:
|
| 42 |
-
17962:
|
| 43 |
-
17429:
|
| 44 |
-
7497:
|
| 45 |
-
24139:
|
| 46 |
-
9801:
|
| 47 |
-
4538:
|
| 48 |
-
24151:
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
}
|
| 68 |
|
| 69 |
def get_as_info(number):
|
| 70 |
r = asn_map.get(number)
|
| 71 |
if r:
|
| 72 |
return r
|
| 73 |
-
|
| 74 |
def get_des(d):
|
| 75 |
for i in lang:
|
| 76 |
if i in d['names']:
|
|
@@ -84,14 +119,14 @@ def get_country(d):
|
|
| 84 |
return r
|
| 85 |
|
| 86 |
def province_match(s):
|
| 87 |
-
arr
|
| 88 |
for i in arr:
|
| 89 |
if i in s:
|
| 90 |
return i
|
| 91 |
return ''
|
| 92 |
|
| 93 |
def de_duplicate(regions):
|
| 94 |
-
regions = filter(bool,
|
| 95 |
ret = []
|
| 96 |
[ret.append(i) for i in regions if i not in ret]
|
| 97 |
return ret
|
|
@@ -100,12 +135,11 @@ def get_addr(ip, mask):
|
|
| 100 |
network = ipaddress.ip_network(f"{ip}/{mask}", strict=False)
|
| 101 |
first_ip = network.network_address
|
| 102 |
return f"{first_ip}/{mask}"
|
| 103 |
-
|
| 104 |
def get_maxmind(ip: str):
|
| 105 |
-
ret = {"ip":
|
| 106 |
asn_info = asn_reader.get(ip)
|
| 107 |
if asn_info:
|
| 108 |
-
as_ = {"number":
|
| 109 |
info = get_as_info(as_["number"])
|
| 110 |
if info:
|
| 111 |
as_["info"] = info
|
|
@@ -115,45 +149,78 @@ def get_maxmind(ip: str):
|
|
| 115 |
ret["addr"] = get_addr(ip, prefix)
|
| 116 |
if not city_info:
|
| 117 |
return ret
|
| 118 |
-
|
|
|
|
| 119 |
if "location" in city_info:
|
| 120 |
location = city_info["location"]
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
"
|
| 124 |
-
|
| 125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
if "country" in city_info:
|
| 127 |
country_code = city_info["country"]["iso_code"]
|
| 128 |
country_name = get_country(city_info["country"])
|
| 129 |
-
ret["country"] = {"code":
|
| 130 |
-
|
| 131 |
if "registered_country" in city_info:
|
| 132 |
registered_country_code = city_info["registered_country"]["iso_code"]
|
| 133 |
-
ret["registered_country"] = {"code":
|
| 134 |
-
|
| 135 |
regions = [get_des(i) for i in city_info.get('subdivisions', [])]
|
| 136 |
|
| 137 |
if "city" in city_info:
|
| 138 |
c = get_des(city_info["city"])
|
| 139 |
-
if (not regions or c not in regions[-1])
|
| 140 |
regions.append(c)
|
| 141 |
-
|
| 142 |
regions = de_duplicate(regions)
|
| 143 |
if regions:
|
| 144 |
ret["regions"] = regions
|
| 145 |
-
|
| 146 |
return ret
|
| 147 |
|
| 148 |
-
def get_cn(ip:
|
| 149 |
ret, prefix = cn_reader.get_with_prefix_len(ip)
|
| 150 |
if not ret:
|
| 151 |
return
|
| 152 |
info["addr"] = get_addr(ip, prefix)
|
| 153 |
-
regions = de_duplicate([ret["province"],
|
| 154 |
if regions:
|
| 155 |
info["regions"] = regions
|
| 156 |
-
info["regions_short"] = de_duplicate([province_match(ret["province"]),
|
| 157 |
if "as" not in info:
|
| 158 |
info["as"] = {}
|
| 159 |
info["as"]["info"] = ret['isp']
|
|
@@ -164,7 +231,7 @@ def get_cn(ip: str, info={}):
|
|
| 164 |
def get_ip_info(ip):
|
| 165 |
info = get_maxmind(ip)
|
| 166 |
if "country" in info and info["country"]["code"] == "CN" and ("registered_country" not in info or info["registered_country"]["code"] == "CN"):
|
| 167 |
-
get_cn(ip,
|
| 168 |
return info
|
| 169 |
|
| 170 |
def query():
|
|
@@ -172,25 +239,33 @@ def query():
|
|
| 172 |
try:
|
| 173 |
ip = input('IP: \t').strip()
|
| 174 |
info = get_ip_info(ip)
|
|
|
|
| 175 |
print(f"网段:\t{info['addr']}")
|
|
|
|
|
|
|
| 176 |
if "location" in info:
|
| 177 |
print(f"经纬度:\t{info['location']['latitude']}, {info['location']['longitude']}")
|
|
|
|
| 178 |
if "as" in info:
|
| 179 |
-
print(f"ISP:\t",
|
| 180 |
if "info" in info["as"]:
|
| 181 |
-
print(info["as"]["info"],
|
| 182 |
else:
|
| 183 |
-
print(info["as"]["name"],
|
| 184 |
if "type" in info:
|
| 185 |
-
print(f"({info['type']})",
|
| 186 |
-
print(f"ASN{info['as']['number']}",
|
| 187 |
print(info['as']["name"])
|
|
|
|
| 188 |
if "registered_country" in info and ("country" not in info or info["country"]["code"] != info["registered_country"]["code"]):
|
| 189 |
print(f"注册地:\t{info['registered_country']['name']}")
|
|
|
|
| 190 |
if "country" in info:
|
| 191 |
print(f"使用地:\t{info['country']['name']}")
|
|
|
|
| 192 |
if "regions" in info:
|
| 193 |
print(f"位置: \t{' '.join(info['regions'])}")
|
|
|
|
| 194 |
except Exception as e:
|
| 195 |
print(e)
|
| 196 |
raise e
|
|
@@ -201,9 +276,14 @@ app = FastAPI()
|
|
| 201 |
|
| 202 |
@app.get("/")
|
| 203 |
async def api(request: Request, ip: str = None):
|
|
|
|
| 204 |
client_ip = request.headers.get("x-forwarded-for") or request.headers.get("x-real-ip") or request.client.host
|
| 205 |
query_ip = ip.strip() if ip else client_ip
|
|
|
|
|
|
|
| 206 |
result = get_ip_info(query_ip)
|
|
|
|
|
|
|
| 207 |
log_data = {
|
| 208 |
"时间": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
| 209 |
"访问IP": client_ip,
|
|
@@ -211,13 +291,21 @@ async def api(request: Request, ip: str = None):
|
|
| 211 |
"请求头": dict(request.headers),
|
| 212 |
"查询结果": result
|
| 213 |
}
|
|
|
|
|
|
|
| 214 |
logger.info(json.dumps(log_data, ensure_ascii=False))
|
|
|
|
| 215 |
return result
|
| 216 |
|
| 217 |
@app.get("/{ip}")
|
| 218 |
async def path_api(request: Request, ip: str):
|
|
|
|
| 219 |
client_ip = request.headers.get("x-forwarded-for") or request.headers.get("x-real-ip") or request.client.host
|
|
|
|
|
|
|
| 220 |
result = get_ip_info(ip)
|
|
|
|
|
|
|
| 221 |
log_data = {
|
| 222 |
"时间": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
| 223 |
"访问IP": client_ip,
|
|
@@ -225,10 +313,13 @@ async def path_api(request: Request, ip: str):
|
|
| 225 |
"请求头": dict(request.headers),
|
| 226 |
"查询结果": result
|
| 227 |
}
|
|
|
|
|
|
|
| 228 |
logger.info(json.dumps(log_data, ensure_ascii=False))
|
|
|
|
| 229 |
return result
|
| 230 |
|
| 231 |
if __name__ == '__main__':
|
| 232 |
query()
|
| 233 |
import uvicorn
|
| 234 |
-
uvicorn.run(app, host="0.0.0.0", port=8080, server_header=False, proxy_headers=True)
|
|
|
|
| 8 |
import os
|
| 9 |
from logging.handlers import RotatingFileHandler
|
| 10 |
|
| 11 |
+
# 定义日志文件路径
|
| 12 |
LOG_FILE = os.path.join('/code', 'ip_query.log')
|
| 13 |
|
| 14 |
+
# 配置日志
|
| 15 |
try:
|
| 16 |
+
# 创建格式化器
|
| 17 |
formatter = logging.Formatter('%(message)s')
|
| 18 |
+
|
| 19 |
+
# 配置处理器
|
| 20 |
log_handler = RotatingFileHandler(
|
| 21 |
LOG_FILE,
|
| 22 |
+
maxBytes=10*1024*1024, # 10MB
|
| 23 |
backupCount=5,
|
| 24 |
encoding='utf-8'
|
| 25 |
)
|
| 26 |
log_handler.setFormatter(formatter)
|
| 27 |
+
|
| 28 |
+
# 获取logger
|
| 29 |
logger = logging.getLogger('ip_query')
|
| 30 |
logger.setLevel(logging.INFO)
|
| 31 |
logger.addHandler(log_handler)
|
| 32 |
+
|
| 33 |
+
# 记录启动日志
|
| 34 |
startup_log = {
|
| 35 |
"时间": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
| 36 |
"事件": "系统启动",
|
| 37 |
"状态": "成功"
|
| 38 |
}
|
| 39 |
logger.info(json.dumps(startup_log, ensure_ascii=False))
|
| 40 |
+
|
| 41 |
except Exception as e:
|
| 42 |
print(f"日志初始化失败: {e}")
|
| 43 |
sys.exit(1)
|
|
|
|
| 45 |
city_reader = maxminddb.open_database('GeoLite2-City.mmdb')
|
| 46 |
asn_reader = maxminddb.open_database('GeoLite2-ASN.mmdb')
|
| 47 |
cn_reader = maxminddb.open_database('GeoCN.mmdb')
|
| 48 |
+
lang = ["zh-CN","en"]
|
| 49 |
asn_map = {
|
| 50 |
+
9812:"东方有线",
|
| 51 |
+
9389:"中国长城",
|
| 52 |
+
17962:"天威视讯",
|
| 53 |
+
17429:"歌华有线",
|
| 54 |
+
7497:"科技网",
|
| 55 |
+
24139:"华数",
|
| 56 |
+
9801:"中关村",
|
| 57 |
+
4538:"教育网",
|
| 58 |
+
24151:"CNNIC",
|
| 59 |
+
|
| 60 |
+
38019:"中国移动",139080:"中国移动",9808:"中国移动",24400:"中国移动",134810:"中国移动",24547:"中国移动",
|
| 61 |
+
56040:"中国移动",56041:"中国移动",56042:"中国移动",56044:"中国移动",132525:"中国移动",56046:"中国移动",
|
| 62 |
+
56047:"中国移动",56048:"中国移动",59257:"中国移动",24444:"中国移动",
|
| 63 |
+
24445:"中国移动",137872:"中国移动",9231:"中国移动",58453:"中国移动",
|
| 64 |
+
|
| 65 |
+
4134:"中国电信",4812:"中国电信",23724:"中国电信",136188:"中国电信",137693:"中国电信",17638:"中国电信",
|
| 66 |
+
140553:"中国电信",4847:"中国电信",140061:"中国电信",136195:"中国电信",17799:"中国电信",139018:"中国电信",
|
| 67 |
+
133776:"中国电信",58772:"中国电信",146966:"中国电信",63527:"中国电信",58539:"中国电信",58540:"中国电信",
|
| 68 |
+
141998:"中国电信",138169:"中国电信",139203:"中国电信",58563:"中电信",137690:"中国电信",63838:"中国电信",
|
| 69 |
+
137694:"中国电信",137698:"中国电信",136167:"中国电信",148969:"中国电信",134764:"中国电信",
|
| 70 |
+
134770:"中国电信",148981:"中国电信",134774:"中国电信",136190:"中国电信",140647:"中国电信",
|
| 71 |
+
132225:"中国电信",140485:"中国电信",4811:"中国电信",131285:"中国电信",137689:"中国电信",
|
| 72 |
+
137692:"中国电信",140636:"中国电信",140638:"中国电信",140345:"中国电信",38283:"中国电信",
|
| 73 |
+
140292:"中国电信",140903:"中国电信",17897:"中国电信",134762:"中国电信",139019:"中国电信",
|
| 74 |
+
141739:"中国电信",141771:"中国电信",134419:"中国电信",140276:"中国电信",58542:"中国电信",
|
| 75 |
+
140278:"中国电信",139767:"中国电信",137688:"中国电信",137691:"中国电信",4809:"中国电信",
|
| 76 |
+
58466:"中国电信",137687:"中国电信",134756:"中国电信",134760:"中国电信",
|
| 77 |
+
133774:"中国电信",133775:"中国电信",4816:"中国电信",134768:"中国电信",
|
| 78 |
+
58461:"中国电信",58519:"��国电信",58520:"中国电信",131325:"中国电信",
|
| 79 |
+
|
| 80 |
+
4837:"中国联通",4808:"中国联通",134542:"中国联通",134543:"中国联通",10099:"中国联通",
|
| 81 |
+
140979:"中国联通",138421:"中国联通",17621:"中国联通",17622:"中国联通",17816:"中国联通",
|
| 82 |
+
140726:"中国联通",17623:"中国联通",136958:"中国联通",9929:"中国联通",58519:"中国联通",
|
| 83 |
+
140716:"中国联通",4847:"中国联通",136959:"中国联通",135061:"中国联通",139007:"中国联通",
|
| 84 |
+
|
| 85 |
+
59019:"金山云",
|
| 86 |
+
135377:"优刻云",
|
| 87 |
+
45062:"网易云",
|
| 88 |
+
137718:"火山引擎",
|
| 89 |
+
37963:"阿里云",45102:"阿里云国际",
|
| 90 |
+
45090:"腾讯云",132203:"腾讯云国际",
|
| 91 |
+
55967:"百度云",38365:"百度云",
|
| 92 |
+
58519:"华为云", 55990:"华为云",136907:"华为云",
|
| 93 |
+
4609:"澳門電訊",
|
| 94 |
+
134773:"珠江宽频",
|
| 95 |
+
1659:"台湾教育网",
|
| 96 |
+
8075:"微软云",
|
| 97 |
+
17421:"中华电信",
|
| 98 |
+
3462:"HiNet",
|
| 99 |
+
13335:"Cloudflare",
|
| 100 |
+
55960:"亚马逊云",14618:"亚马逊云",16509:"亚马逊云",
|
| 101 |
+
15169:"谷歌云",396982:"谷歌云",36492:"谷歌云",
|
| 102 |
}
|
| 103 |
|
| 104 |
def get_as_info(number):
|
| 105 |
r = asn_map.get(number)
|
| 106 |
if r:
|
| 107 |
return r
|
| 108 |
+
|
| 109 |
def get_des(d):
|
| 110 |
for i in lang:
|
| 111 |
if i in d['names']:
|
|
|
|
| 119 |
return r
|
| 120 |
|
| 121 |
def province_match(s):
|
| 122 |
+
arr=['内蒙古','黑龙江','河北','山西','吉林','辽宁','江苏','浙江','安徽','福建','江西','山东','河南','湖北','湖南','广东','海南','四川','贵州','云南','陕西','甘肃','青海','广西','西藏','宁夏','新疆','北京','天津','上海','重庆']
|
| 123 |
for i in arr:
|
| 124 |
if i in s:
|
| 125 |
return i
|
| 126 |
return ''
|
| 127 |
|
| 128 |
def de_duplicate(regions):
|
| 129 |
+
regions = filter(bool,regions)
|
| 130 |
ret = []
|
| 131 |
[ret.append(i) for i in regions if i not in ret]
|
| 132 |
return ret
|
|
|
|
| 135 |
network = ipaddress.ip_network(f"{ip}/{mask}", strict=False)
|
| 136 |
first_ip = network.network_address
|
| 137 |
return f"{first_ip}/{mask}"
|
|
|
|
| 138 |
def get_maxmind(ip: str):
|
| 139 |
+
ret = {"ip":ip}
|
| 140 |
asn_info = asn_reader.get(ip)
|
| 141 |
if asn_info:
|
| 142 |
+
as_ = {"number":asn_info["autonomous_system_number"],"name":asn_info["autonomous_system_organization"]}
|
| 143 |
info = get_as_info(as_["number"])
|
| 144 |
if info:
|
| 145 |
as_["info"] = info
|
|
|
|
| 149 |
ret["addr"] = get_addr(ip, prefix)
|
| 150 |
if not city_info:
|
| 151 |
return ret
|
| 152 |
+
|
| 153 |
+
# 添加经纬度和时区信息
|
| 154 |
if "location" in city_info:
|
| 155 |
location = city_info["location"]
|
| 156 |
+
loc_data = {}
|
| 157 |
+
if "latitude" in location:
|
| 158 |
+
loc_data["latitude"] = location["latitude"]
|
| 159 |
+
if "longitude" in location:
|
| 160 |
+
loc_data["longitude"] = location["longitude"]
|
| 161 |
+
if "time_zone" in location:
|
| 162 |
+
loc_data["timezone"] = location["time_zone"]
|
| 163 |
+
if loc_data:
|
| 164 |
+
ret["location"] = loc_data
|
| 165 |
+
|
| 166 |
+
# 添加大洲信息
|
| 167 |
+
if "continent" in city_info and city_info["continent"]:
|
| 168 |
+
try:
|
| 169 |
+
ret["continent"] = {
|
| 170 |
+
"code": city_info["continent"].get("code"),
|
| 171 |
+
"name": get_des(city_info["continent"]) if "names" in city_info["continent"] else None
|
| 172 |
+
}
|
| 173 |
+
except Exception:
|
| 174 |
+
pass
|
| 175 |
+
|
| 176 |
+
# 添加邮政编码
|
| 177 |
+
if "postal" in city_info and city_info["postal"]:
|
| 178 |
+
postal_code = city_info["postal"].get("code")
|
| 179 |
+
if postal_code:
|
| 180 |
+
ret["postal"] = postal_code
|
| 181 |
+
|
| 182 |
+
# 添加网络特征
|
| 183 |
+
if "traits" in city_info and city_info["traits"]:
|
| 184 |
+
traits = city_info["traits"]
|
| 185 |
+
traits_data = {}
|
| 186 |
+
if "is_anonymous_proxy" in traits:
|
| 187 |
+
traits_data["is_anonymous_proxy"] = traits["is_anonymous_proxy"]
|
| 188 |
+
if "is_satellite_provider" in traits:
|
| 189 |
+
traits_data["is_satellite_provider"] = traits["is_satellite_provider"]
|
| 190 |
+
if traits_data:
|
| 191 |
+
ret["traits"] = traits_data
|
| 192 |
+
|
| 193 |
if "country" in city_info:
|
| 194 |
country_code = city_info["country"]["iso_code"]
|
| 195 |
country_name = get_country(city_info["country"])
|
| 196 |
+
ret["country"] = {"code":country_code,"name":country_name}
|
| 197 |
+
|
| 198 |
if "registered_country" in city_info:
|
| 199 |
registered_country_code = city_info["registered_country"]["iso_code"]
|
| 200 |
+
ret["registered_country"] = {"code":registered_country_code,"name":get_country(city_info["registered_country"])}
|
| 201 |
+
|
| 202 |
regions = [get_des(i) for i in city_info.get('subdivisions', [])]
|
| 203 |
|
| 204 |
if "city" in city_info:
|
| 205 |
c = get_des(city_info["city"])
|
| 206 |
+
if (not regions or c not in regions[-1])and c not in country_name:
|
| 207 |
regions.append(c)
|
| 208 |
+
|
| 209 |
regions = de_duplicate(regions)
|
| 210 |
if regions:
|
| 211 |
ret["regions"] = regions
|
| 212 |
+
|
| 213 |
return ret
|
| 214 |
|
| 215 |
+
def get_cn(ip:str, info={}):
|
| 216 |
ret, prefix = cn_reader.get_with_prefix_len(ip)
|
| 217 |
if not ret:
|
| 218 |
return
|
| 219 |
info["addr"] = get_addr(ip, prefix)
|
| 220 |
+
regions = de_duplicate([ret["province"],ret["city"],ret["districts"]])
|
| 221 |
if regions:
|
| 222 |
info["regions"] = regions
|
| 223 |
+
info["regions_short"] = de_duplicate([province_match(ret["province"]),ret["city"].replace('市',''),ret["districts"]])
|
| 224 |
if "as" not in info:
|
| 225 |
info["as"] = {}
|
| 226 |
info["as"]["info"] = ret['isp']
|
|
|
|
| 231 |
def get_ip_info(ip):
|
| 232 |
info = get_maxmind(ip)
|
| 233 |
if "country" in info and info["country"]["code"] == "CN" and ("registered_country" not in info or info["registered_country"]["code"] == "CN"):
|
| 234 |
+
get_cn(ip,info)
|
| 235 |
return info
|
| 236 |
|
| 237 |
def query():
|
|
|
|
| 239 |
try:
|
| 240 |
ip = input('IP: \t').strip()
|
| 241 |
info = get_ip_info(ip)
|
| 242 |
+
|
| 243 |
print(f"网段:\t{info['addr']}")
|
| 244 |
+
|
| 245 |
+
# 添加经纬度显示
|
| 246 |
if "location" in info:
|
| 247 |
print(f"经纬度:\t{info['location']['latitude']}, {info['location']['longitude']}")
|
| 248 |
+
|
| 249 |
if "as" in info:
|
| 250 |
+
print(f"ISP:\t",end=' ')
|
| 251 |
if "info" in info["as"]:
|
| 252 |
+
print(info["as"]["info"],end=' ')
|
| 253 |
else:
|
| 254 |
+
print(info["as"]["name"],end=' ')
|
| 255 |
if "type" in info:
|
| 256 |
+
print(f"({info['type']})",end=' ')
|
| 257 |
+
print(f"ASN{info['as']['number']}",end=' ')
|
| 258 |
print(info['as']["name"])
|
| 259 |
+
|
| 260 |
if "registered_country" in info and ("country" not in info or info["country"]["code"] != info["registered_country"]["code"]):
|
| 261 |
print(f"注册地:\t{info['registered_country']['name']}")
|
| 262 |
+
|
| 263 |
if "country" in info:
|
| 264 |
print(f"使用地:\t{info['country']['name']}")
|
| 265 |
+
|
| 266 |
if "regions" in info:
|
| 267 |
print(f"位置: \t{' '.join(info['regions'])}")
|
| 268 |
+
|
| 269 |
except Exception as e:
|
| 270 |
print(e)
|
| 271 |
raise e
|
|
|
|
| 276 |
|
| 277 |
@app.get("/")
|
| 278 |
async def api(request: Request, ip: str = None):
|
| 279 |
+
# 获取请求信息
|
| 280 |
client_ip = request.headers.get("x-forwarded-for") or request.headers.get("x-real-ip") or request.client.host
|
| 281 |
query_ip = ip.strip() if ip else client_ip
|
| 282 |
+
|
| 283 |
+
# 获取IP信息
|
| 284 |
result = get_ip_info(query_ip)
|
| 285 |
+
|
| 286 |
+
# 构建日志信息
|
| 287 |
log_data = {
|
| 288 |
"时间": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
| 289 |
"访问IP": client_ip,
|
|
|
|
| 291 |
"请求头": dict(request.headers),
|
| 292 |
"查询结果": result
|
| 293 |
}
|
| 294 |
+
|
| 295 |
+
# 使用logger.info而不是logging.info
|
| 296 |
logger.info(json.dumps(log_data, ensure_ascii=False))
|
| 297 |
+
|
| 298 |
return result
|
| 299 |
|
| 300 |
@app.get("/{ip}")
|
| 301 |
async def path_api(request: Request, ip: str):
|
| 302 |
+
# 获取请求信息
|
| 303 |
client_ip = request.headers.get("x-forwarded-for") or request.headers.get("x-real-ip") or request.client.host
|
| 304 |
+
|
| 305 |
+
# 获取IP信息
|
| 306 |
result = get_ip_info(ip)
|
| 307 |
+
|
| 308 |
+
# 构建日志信息
|
| 309 |
log_data = {
|
| 310 |
"时间": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
| 311 |
"访问IP": client_ip,
|
|
|
|
| 313 |
"请求头": dict(request.headers),
|
| 314 |
"查询结果": result
|
| 315 |
}
|
| 316 |
+
|
| 317 |
+
# 使用logger.info而不是logging.info
|
| 318 |
logger.info(json.dumps(log_data, ensure_ascii=False))
|
| 319 |
+
|
| 320 |
return result
|
| 321 |
|
| 322 |
if __name__ == '__main__':
|
| 323 |
query()
|
| 324 |
import uvicorn
|
| 325 |
+
uvicorn.run(app, host="0.0.0.0", port=8080, server_header=False, proxy_headers=True)
|