fix: _parse

This commit is contained in:
austnv
2026-06-14 16:46:18 +03:00
parent ba960d5d67
commit a2d57c4080
+26 -17
View File
@@ -66,30 +66,39 @@ class IPInfo:
def _parse(self, html: str) -> Optional[IPInfoModel]: def _parse(self, html: str) -> Optional[IPInfoModel]:
"""Парсит HTML и возвращает модель""" """Парсит HTML и возвращает модель"""
soup = BeautifulSoup(html, 'html.parser') soup = BeautifulSoup(html, 'html.parser')
script = soup.find('script', type='application/ld+json') scripts = soup.find_all('script', type='application/ld+json')
if not script or not script.string: if not scripts:
return None return None
try: # Ищем первый скрипт с типом DataFeed
data: Dict = json.loads(script.string.strip()) data = None
except json.JSONDecodeError: for script in scripts:
if not script.string:
continue
try:
parsed = json.loads(script.string.strip())
if parsed.get('@type') == 'DataFeed':
data = parsed
break
except json.JSONDecodeError:
continue
if data is None:
return None return None
if data.get('@type') != 'DataFeed':
return None
# Базовые поля # Базовые поля
result = IPInfoModel( result = IPInfoModel(
ip=data.get('name', ''), ip=data.get('name', ''),
url=data.get('url') url=data.get('url')
) )
# Парсим локацию # Парсим локацию
location = data.get('contentLocation', {}) location = data.get('contentLocation', {})
address = location.get('address', {}) address = location.get('address', {})
geo = location.get('geo', {}) geo = location.get('geo', {})
result.location = LocationModel( result.location = LocationModel(
city=address.get('addressLocality'), city=address.get('addressLocality'),
region=address.get('addressRegion'), region=address.get('addressRegion'),
@@ -99,20 +108,20 @@ class IPInfo:
longitude=geo.get('longitude'), longitude=geo.get('longitude'),
timezone=self._find_value(data, 'Timezone') timezone=self._find_value(data, 'Timezone')
) )
# Парсим ASN # Парсим ASN
result.asn = ASNModel( result.asn = ASNModel(
asn=self._find_value(data, 'ASN'), asn=self._find_value(data, 'ASN'),
name=self._find_value(data, 'AS Name'), name=self._find_value(data, 'AS Name'),
route=self._find_value(data, 'AS Route') route=self._find_value(data, 'AS Route')
) )
# Парсим компанию # Парсим компанию
result.company = CompanyModel( result.company = CompanyModel(
name=self._find_value(data, 'Company Name'), name=self._find_value(data, 'Company Name'),
abuse_contact=self._find_value(data, 'Abuse Contact') abuse_contact=self._find_value(data, 'Abuse Contact')
) )
# Парсим безопасность # Парсим безопасность
result.security = SecurityModel( result.security = SecurityModel(
vpn=self._find_bool(data, 'VPN'), vpn=self._find_bool(data, 'VPN'),
@@ -120,7 +129,7 @@ class IPInfo:
tor=self._find_bool(data, 'Tor'), tor=self._find_bool(data, 'Tor'),
hosting=self._find_bool(data, 'Hosting') hosting=self._find_bool(data, 'Hosting')
) )
return result return result
def _find_value(self, data: Dict, name: str) -> Optional[str]: def _find_value(self, data: Dict, name: str) -> Optional[str]: