Files
152-fz-scanner/scanner/checks/cookie_banner.py
T
neo de18090304 🏗 Фаза 1-4: Архитектура, ядро, проверки, API, генератор отчетов
- scanner/engine.py — Playwright-движок сканирования
- scanner/models.py — Pydantic модели
- scanner/checks/ — 5 проверок (cookie, privacy, forms, server, external)
- api/server.py — FastAPI REST API
- reports/generator.py — PDF через WeasyPrint + Jinja2
- main.py — CLI + сервер

Проверки:
✅ cookie_banner — поиск cookie-баннера
✅ privacy_link — проверка ссылки на политику
✅ form_checkbox — проверка чекбоксов согласия
✅ server_location — геолокация сервера (RФ или нет)
✅ external_scripts — внешние скрипты аналитики
2026-06-09 21:10:21 +05:00

90 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Проверка наличия cookie-баннера (уведомления о cookies).
Согласно 152-ФЗ, сайт обязан получать согласие пользователя
на обработку персональных данных, включая cookies.
"""
from __future__ import annotations
import re
from playwright.async_api import Page
from scanner.checks.base import BaseCheck
from scanner.models import CheckResult, RiskLevel
class CookieBannerCheck(BaseCheck):
"""Проверяет наличие cookie-баннера на сайте."""
name = "cookie_banner"
title = "Cookie-баннер"
description = "Проверяет, отображается ли на сайте уведомление о cookie"
risk_on_fail = RiskLevel.HIGH
default_weight = 15
# Паттерны для поиска cookie-баннера
COOKIE_PATTERNS = [
r"cookie",
r"куки",
r"уведомление\s*о\s*cookie",
r"согласие\s*на\s*использование\s*cookie",
r"we\s*use\s*cookies",
r"privacy\s*policy",
r"данные\s*пользователя",
r"обработка\s*персональных\s*данных",
r"personal\s*data",
r"consent",
r"согласие",
]
async def check(self, page: Page, url: str) -> CheckResult:
try:
# Получаем весь текст страницы (включая динамически загруженный)
page_text = await page.evaluate("() => document.body.innerText")
page_html = await page.evaluate("() => document.documentElement.outerHTML")
# Ищем cookie-баннер по видимым элементам
cookie_elements = await page.query_selector_all(
'[id*="cookie"], [class*="cookie"], [id*="consent"], [class*="consent"], [id*="privacy"], [class*="privacy"], [id*="policy"], [class*="policy"]'
)
found_banner = False
banner_texts = []
for el in cookie_elements:
text = await el.inner_text()
if text:
banner_texts.append(text[:200])
# Также ищем по тексту всей страницы
has_keyword = any(
re.search(pattern, page_text, re.IGNORECASE | re.UNICODE)
for pattern in self.COOKIE_PATTERNS
)
if banner_texts:
found_banner = True
return self._pass_result(
message=f"Найден cookie-баннер ({len(banner_texts)} элементов)",
details={
"banner_count": len(banner_texts),
"sample_text": banner_texts[0][:100],
},
)
if has_keyword:
return self._pass_result(
message="На странице найдены упоминания cookie/согласия",
details={"keyword_found": True},
)
return self._fail_result(
message="Cookie-баннер не найден. Сайт собирает данные без явного согласия.",
details={
"page_text_sample": page_text[:200],
"search_patterns": self.COOKIE_PATTERNS,
},
)
except Exception as e:
return self._error_result(message=f"Ошибка при проверке cookie-баннера: {str(e)}")