|
@@ -2,6 +2,7 @@
|
|
|
# @File : IPWeatherObject.py
|
|
|
# @Time : 2023/8/16 8:56
|
|
|
import datetime
|
|
|
+import json
|
|
|
|
|
|
import geoip2.webservice
|
|
|
import requests
|
|
@@ -235,3 +236,84 @@ class OpenWeatherMap:
|
|
|
temp = str(int(res_data['main']['temp']))
|
|
|
humidity = str(int(res_data['main']['humidity']))
|
|
|
return temp, humidity
|
|
|
+
|
|
|
+
|
|
|
+class Findip:
|
|
|
+ """
|
|
|
+ findip 查询国外ip
|
|
|
+ 同时保存ip信息
|
|
|
+ https://www.findip.net/Main/Index
|
|
|
+ """
|
|
|
+
|
|
|
+ def __init__(self, ip):
|
|
|
+ self.token = 'bb51156441ec401caec0476864ec2b93'
|
|
|
+ self.ip = ip
|
|
|
+ self.lat = 0.0
|
|
|
+ self.lon = 0.0
|
|
|
+ self.city = ''
|
|
|
+ self.region = ''
|
|
|
+ self.country_code = ''
|
|
|
+
|
|
|
+ try:
|
|
|
+ # 调用findip API获取IP信息
|
|
|
+ self._get_ip_info()
|
|
|
+
|
|
|
+ # 保存ip信息
|
|
|
+ ip_addr_data = {
|
|
|
+ 'ip': self.ip,
|
|
|
+ 'lat': self.lat,
|
|
|
+ 'lon': self.lon,
|
|
|
+ 'city': self.city,
|
|
|
+ 'region': self.region,
|
|
|
+ 'country_code': self.country_code,
|
|
|
+ 'is_geoip2': True # 是否为GeoIP2解析
|
|
|
+ }
|
|
|
+ IPAddr.objects.create(**ip_addr_data)
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ LOGGER.error('FindIP解析ip异常:error_line:{}, error_msg:{}'.format(
|
|
|
+ e.__traceback__.tb_lineno, repr(e)
|
|
|
+ ))
|
|
|
+
|
|
|
+ def _get_ip_info(self):
|
|
|
+ """调用findip API并解析返回结果"""
|
|
|
+ try:
|
|
|
+ # 构建API请求URL
|
|
|
+ url = f"https://api.findip.net/{self.ip}/?token={self.token}"
|
|
|
+ response = requests.get(url, timeout=10)
|
|
|
+
|
|
|
+ # 检查请求是否成功
|
|
|
+ if response.status_code == 200:
|
|
|
+ data = response.json()
|
|
|
+ self._parse_response(data)
|
|
|
+ else:
|
|
|
+ raise Exception(f"API请求失败,状态码: {response.status_code}")
|
|
|
+
|
|
|
+ except requests.RequestException as re:
|
|
|
+ raise Exception(f"请求异常: {str(re)}")
|
|
|
+ except json.JSONDecodeError as jde:
|
|
|
+ raise Exception(f"JSON解析异常: {str(jde)}")
|
|
|
+
|
|
|
+ def _parse_response(self, data):
|
|
|
+ """解析API返回的JSON数据并提取所需字段"""
|
|
|
+ # 提取经纬度并保留两位小数
|
|
|
+ if 'location' in data and data['location']:
|
|
|
+ self.lat = round(data['location'].get('latitude', 0.0), 2)
|
|
|
+ self.lon = round(data['location'].get('longitude', 0.0), 2)
|
|
|
+
|
|
|
+ # 提取国家代码
|
|
|
+ if 'country' in data and data['country'] and 'iso_code' in data['country']:
|
|
|
+ self.country_code = data['country']['iso_code']
|
|
|
+
|
|
|
+ # 提取城市名称(优先中文,其次英文)
|
|
|
+ if 'city' in data and data['city'] and 'names' in data['city']:
|
|
|
+ names = data['city']['names']
|
|
|
+ self.city = names.get('zh-CN', names.get('en', ''))
|
|
|
+
|
|
|
+ # 提取地区名称(优先中文,其次英文)
|
|
|
+ if 'subdivisions' in data and data['subdivisions']:
|
|
|
+ # 取第一个细分区域(通常是省/州级别)
|
|
|
+ first_subdivision = data['subdivisions'][0]
|
|
|
+ if 'names' in first_subdivision:
|
|
|
+ names = first_subdivision['names']
|
|
|
+ self.region = names.get('zh-CN', names.get('en', ''))
|