88 lines
3.9 KiB
Python
88 lines
3.9 KiB
Python
import json
|
||
import os
|
||
import subprocess
|
||
import time
|
||
from pathlib import Path
|
||
from playwright.sync_api import sync_playwright
|
||
|
||
# --- CONFIG (Inside Container) ---
|
||
DATA_FILE = "/app/found_appeals.json"
|
||
STORAGE_ROOT = Path("/app/harvest_archive")
|
||
NAS_PATH = "/app/downloads/nas" # Мониторится докером и маунтится на NAS
|
||
BOT_TOKEN = "8725618164:AAH1tGalq-pw1l0t4P5c0sdLkCVJdh7IE7M"
|
||
CHAT_ID = "197957361"
|
||
|
||
def send_tg_status(current, total, name):
|
||
perc = round(current / total * 100)
|
||
bar = "█" * (perc // 10) + "░" * (10 - (perc // 10))
|
||
msg = f"🌾 **ЖАТВА ГИС ЖКХ**\n\n[{bar}] {perc}%\nОбработано: {current}/{total}\n\n📦 **Взято в архив:**\n{name}"
|
||
subprocess.run(["curl", "-s", "-X", "POST", f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage",
|
||
"-d", f"chat_id={CHAT_ID}&text={msg}&parse_mode=markdown"])
|
||
|
||
def run_harvest():
|
||
if not os.path.exists(DATA_FILE):
|
||
print("❌ Список целей не найден!")
|
||
return
|
||
|
||
with open(DATA_FILE, "r") as f:
|
||
queue = json.load(f)
|
||
|
||
total = len(queue)
|
||
print(f"[*] Начинаем жатву {total} обращений...")
|
||
|
||
with sync_playwright() as p:
|
||
# Пытаемся подключиться к уже запущенному на дисплее браузеру
|
||
browser = p.chromium.connect_over_cdp("http://127.0.0.1:9222")
|
||
page = browser.contexts[0].pages[0]
|
||
|
||
for index, item in enumerate(queue):
|
||
try:
|
||
num = item['number'][:100].replace('/', '_').replace(' ', '_')
|
||
print(f"[{index+1}/{total}] Обработка: {num}")
|
||
|
||
case_dir = STORAGE_ROOT / num
|
||
case_dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
# 1. Прямой переход (SPA)
|
||
page.goto("https://my.dom.gosuslugi.ru" + item['href'])
|
||
page.wait_for_load_state("networkidle")
|
||
time.sleep(15) # Увеличим время на прогрузку тяжелого интерфейса
|
||
|
||
# 2. Скриншот
|
||
screenshot_path = case_dir / "timestamp_evidence.png"
|
||
page.screenshot(path=str(screenshot_path), full_page=True)
|
||
print(f"✅ Скриншот сохранен.")
|
||
|
||
# 3. Скачивание
|
||
download_btn = page.get_by_text("Скачать все").first
|
||
if download_btn.is_visible():
|
||
with page.expect_download(timeout=120000) as download_info:
|
||
download_btn.click()
|
||
download = download_info.value
|
||
zip_path = case_dir / f"archive.zip"
|
||
download.save_as(str(zip_path))
|
||
|
||
# Распаковка
|
||
subprocess.run(["unzip", "-o", str(zip_path), "-d", str(case_dir)])
|
||
|
||
# Копируем на NAS (маунтится через докер)
|
||
nas_case_dir = Path(NAS_PATH) / num
|
||
nas_case_dir.mkdir(parents=True, exist_ok=True)
|
||
subprocess.run(f"cp -r {case_dir}/* {nas_case_dir}/", shell=True)
|
||
|
||
print(f"✅ Вложения выкачаны и синхронизированы с NAS.")
|
||
else:
|
||
print("[-] Кнопка 'Скачать все' не найдена.")
|
||
|
||
send_tg_status(index + 1, total, item['number'][:50])
|
||
|
||
except Exception as e:
|
||
print(f"❌ Ошибка на кейсе {index}: {e}")
|
||
page.goto("https://my.dom.gosuslugi.ru/citizen-cabinet/#!/appeals/applicant/search")
|
||
time.sleep(5)
|
||
|
||
browser.close()
|
||
|
||
if __name__ == "__main__":
|
||
os.makedirs(STORAGE_ROOT, exist_ok=True)
|
||
run_harvest()
|