88 lines
4 KiB
Python
88 lines
4 KiB
Python
from playwright.sync_api import sync_playwright
|
||
import time
|
||
import os
|
||
import json
|
||
|
||
EXPORT_DIR = "/app/exports"
|
||
API_LOG_FILE = os.path.join(EXPORT_DIR, "api_responses.log")
|
||
|
||
if not os.path.exists(EXPORT_DIR):
|
||
os.makedirs(EXPORT_DIR)
|
||
|
||
# Очищаем лог перед новым запуском
|
||
with open(API_LOG_FILE, "w", encoding="utf-8") as f:
|
||
f.write("")
|
||
|
||
print("🚀 Запускаем Умного Робота-Перехватчика ГИС ЖКХ...")
|
||
|
||
def handle_response(response):
|
||
# Ловим только JSON ответы, чтобы найти внутренние API Госуслуг
|
||
if "application/json" in response.headers.get("content-type", ""):
|
||
try:
|
||
url = response.url
|
||
# Игнорируем метрики и мусорные запросы
|
||
if "metric" in url or "log" in url or "stat" in url:
|
||
return
|
||
|
||
body = response.json()
|
||
|
||
# Сохраняем интересные ответы в лог для анализа
|
||
# Нас интересуют ответы, где есть списки элементов (массивы) или файлы
|
||
if isinstance(body, dict) or isinstance(body, list):
|
||
# Просто чтобы не писать гигантские дампы, пишем URL и начало ответа
|
||
with open(API_LOG_FILE, "a", encoding="utf-8") as f:
|
||
f.write(f"\\n--- URL: {url} ---\\n")
|
||
json.dump(body, f, ensure_ascii=False, indent=2)
|
||
f.write("\\n")
|
||
|
||
except Exception as e:
|
||
pass # Игнорируем ошибки парсинга (иногда JSON бывает битым или пустым)
|
||
|
||
with sync_playwright() as p:
|
||
browser = p.chromium.launch_persistent_context(
|
||
user_data_dir="/app/browser_context",
|
||
headless=True,
|
||
args=[
|
||
'--no-sandbox',
|
||
'--disable-setuid-sandbox',
|
||
'--disable-dev-shm-usage',
|
||
'--disable-gpu',
|
||
'--window-size=1920,1080'
|
||
]
|
||
)
|
||
|
||
page = browser.pages[0]
|
||
|
||
# Включаем прослушку всех ответов от сервера!
|
||
page.on("response", handle_response)
|
||
|
||
print("🌐 Подключаемся к Личному кабинету...")
|
||
|
||
# Задаем список прямых ссылок (роутов) для обхода
|
||
routes = [
|
||
{"name": "Main", "url": "https://dom.gosuslugi.ru/#!/main"},
|
||
{"name": "Appeals", "url": "https://dom.gosuslugi.ru/#!/appeals"}, # Обращения
|
||
{"name": "Bills", "url": "https://dom.gosuslugi.ru/#!/bills"}, # Счета
|
||
{"name": "Voting", "url": "https://dom.gosuslugi.ru/#!/voting"} # Голосования
|
||
]
|
||
|
||
for route in routes:
|
||
print(f"\\n➡️ Переход в раздел: {route['name']}")
|
||
try:
|
||
page.goto(route['url'])
|
||
# Ждем 10 секунд, чтобы API успело отдать все JSON с документами
|
||
print("⏳ Ожидание загрузки данных через API (10 сек)...")
|
||
page.wait_for_timeout(10000)
|
||
|
||
scr_name = f"02_{route['name']}_view.png"
|
||
page.screenshot(path=os.path.join(EXPORT_DIR, scr_name), full_page=True)
|
||
print(f"📸 Скриншот раздела сохранен: {scr_name}")
|
||
|
||
except Exception as e:
|
||
print(f"❌ Ошибка в разделе {route['name']}: {e}")
|
||
|
||
browser.close()
|
||
|
||
print("\\n🏁 Сбор данных завершен!")
|
||
print(f"📂 Лог API запросов сохранен в: {API_LOG_FILE}")
|
||
print("🕵️♂️ Теперь мы можем проанализировать этот лог и вытащить оттуда прямые ссылки на скачивание PDF-файлов!")
|