77from user_agents import parse
88
99from backend .app .common .log import log
10+ from backend .app .common .redis import redis_client
1011from backend .app .core .conf import settings
1112from backend .app .core .path_conf import IP2REGION_XDB
1213
@@ -47,7 +48,7 @@ async def get_location_online(ip: str, user_agent: str) -> dict | None:
4748
4849
4950@sync_to_async
50- def get_location_offline (ip : str ) -> list [ str ] | None :
51+ def get_location_offline (ip : str ) -> dict | None :
5152 """
5253 离线获取 ip 地址属地,无法保证准确率,100%可用
5354
@@ -59,8 +60,12 @@ def get_location_offline(ip: str) -> list[str] | None:
5960 searcher = XdbSearcher (contentBuff = cb )
6061 data = searcher .search (ip )
6162 searcher .close ()
62- location_info = data .split ('|' )
63- return location_info
63+ data = data .split ('|' )
64+ return {
65+ 'country' : data [0 ] if data [0 ] != '0' else None ,
66+ 'regionName' : data [2 ] if data [2 ] != '0' else None ,
67+ 'city' : data [3 ] if data [3 ] != '0' else None ,
68+ }
6469 except Exception as e :
6570 log .error (f'离线获取 ip 地址属地失败,错误信息:{ e } ' )
6671 return None
@@ -69,18 +74,22 @@ def get_location_offline(ip: str) -> list[str] | None:
6974async def parse_ip_info (request : Request ) -> tuple [str , str , str , str ]:
7075 country , region , city = None , None , None
7176 ip = await get_request_ip (request )
77+ location = await redis_client .get (f'{ settings .IP_LOCATION_REDIS_PREFIX } :{ ip } ' )
78+ if location :
79+ country , region , city = location .split (' ' )
80+ return ip , country , region , city
7281 if settings .LOCATION_PARSE == 'online' :
7382 location_info = await get_location_online (ip , request .headers .get ('User-Agent' ))
74- if location_info :
75- country = location_info .get ('country' )
76- region = location_info .get ('regionName' )
77- city = location_info .get ('city' )
7883 elif settings .LOCATION_PARSE == 'offline' :
7984 location_info = await get_location_offline (ip )
80- if location_info :
81- country = location_info [0 ] if location_info [0 ] != '0' else None
82- region = location_info [2 ] if location_info [2 ] != '0' else None
83- city = location_info [3 ] if location_info [3 ] != '0' else None
85+ else :
86+ location_info = None
87+ if location_info :
88+ country = location_info .get ('country' )
89+ region = location_info .get ('regionName' )
90+ city = location_info .get ('city' )
91+ await redis_client .set (f'{ settings .IP_LOCATION_REDIS_PREFIX } :{ ip } ' , f'{ country } { region } { city } ' ,
92+ ex = settings .IP_LOCATION_EXPIRE_SECONDS )
8493 return ip , country , region , city
8594
8695
0 commit comments