""" Проверка наличия 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)}")