v2.0: исправлены критические баги, добавлены 4 новые проверки, 4-фазный cookie-аудит, retry-логика, YAML-словари, LLM-анализ, тесты
Исправлено: - engine: _calculate_score() при ошибке загрузки (score не 100 для мёртвых сайтов) - privacy_link: замена page.goto() на aiohttp (гонка данных) - form_checkbox: 3-уровневый поиск label + dark-pattern detection - server_location: синхронный urllib → aiohttp - api/server: перепутанные request/response модели в batch - main.py: csv --checks флаг - engine: фазовая модель (cookie_audit отдельно, остальные параллельно) - engine: retry-логика (3 попытки, exponential backoff) - PDF: emoji заменены на текст (WeasyPrint) Добавлено: - consent_doc: проверка отдельного согласия на обработку ПД - operator_info: проверка ИНН/ОГРН/DPO (читает главную + политику) - cookie_audit: 4-фазный аудит (load→detect→reject→compare) - llm_policy: опциональный LLM-анализ 16 разделов (--deep) - external_scripts: YAML-словари trackers.yaml (critical/warning/russian) - logging (output.py), .gitignore, pyproject.toml - smoke-тесты (16/16)
This commit is contained in:
1 parent
7fb417dad5
commit
b9db935389
24 files changed
+1725
-286
No files matched your search
@@ -79,39 +79,34 @@ class ServerLocationCheck(BaseCheck):
|
||||
return self._error_result(message=f"Ошибка при проверке геолокации: {str(e)}")
|
||||
|
||||
async def _get_country(self, ip: str) -> str | None:
|
||||
"""Получает страну по IP через публичный API."""
|
||||
"""Получает страну по IP через публичный API (асинхронно)."""
|
||||
try:
|
||||
import urllib.request
|
||||
import json
|
||||
import aiohttp
|
||||
|
||||
# Пробуем несколько бесплатных API
|
||||
apis = [
|
||||
f"https://ipapi.co/{ip}/json/",
|
||||
f"https://ip-api.com/json/{ip}?fields=country",
|
||||
f"https://api.ipgeolocation.io/ipgeo?ip={ip}",
|
||||
]
|
||||
|
||||
for api_url in apis:
|
||||
try:
|
||||
req = urllib.request.Request(
|
||||
api_url,
|
||||
headers={"User-Agent": "Mozilla/5.0"}
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=5) as response:
|
||||
data = json.loads(response.read().decode())
|
||||
|
||||
# ipapi.co формат
|
||||
if "country_name" in data:
|
||||
return data["country_name"]
|
||||
# ip-api.com формат
|
||||
if "country" in data:
|
||||
return data["country"]
|
||||
# ipgeolocation формат
|
||||
if "country_name" in data:
|
||||
return data["country_name"]
|
||||
|
||||
except Exception:
|
||||
continue
|
||||
async with aiohttp.ClientSession() as session:
|
||||
for api_url in apis:
|
||||
try:
|
||||
async with session.get(
|
||||
api_url,
|
||||
headers={"User-Agent": "Mozilla/5.0"},
|
||||
timeout=aiohttp.ClientTimeout(total=5),
|
||||
) as response:
|
||||
if response.status != 200:
|
||||
continue
|
||||
data = await response.json()
|
||||
# ipapi.co формат
|
||||
if "country_name" in data:
|
||||
return data["country_name"]
|
||||
# ip-api.com формат
|
||||
if "country" in data:
|
||||
return data["country"]
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
return None
|
||||
|
||||
|
||||
Reference in new issue
Block a user