domovoy_bot/scraper_gis/mcp_smart_parser.py

88 lines
4 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

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-файлов!")