domovoy_bot/scraper_gis/services/gis_harvester/contract_harvester_v2.py

104 lines
4.7 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.

import os
import subprocess
import time
import re
from pathlib import Path
from playwright.sync_api import sync_playwright
# --- CONFIG ---
STORAGE_ROOT = Path("/app/services/gis_harvester/contracts")
NAS_IP = "192.168.10.105"
NAS_PATH = "/volume1/web/legal/gis/contracts"
BOT_TOKEN = "8725618164:AAH1tGalq-pw1l0t4P5c0sdLkCVJdh7IE7M"
CHAT_ID = "197957361"
def send_tg_status(msg):
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 sync_to_nas(local_path, remote_folder):
target = f"{NAS_PATH}/{remote_folder}"
subprocess.run(["ssh", f"matrixhasyou@{NAS_IP}", f"mkdir -p '{target}'"])
for f in os.listdir(local_path):
src = local_path / f
dst = f"{target}/{f}"
with open(src, "rb") as fd:
subprocess.run(["ssh", f"matrixhasyou@{NAS_IP}", f"cat > '{dst}'"], stdin=fd)
def run_harvest():
with sync_playwright() as p:
try:
browser = p.chromium.connect_over_cdp("http://127.0.0.1:9222")
page = browser.contexts[0].pages[0]
print("[*] Анализ списка договоров на экране...")
# Находим все ссылки, содержащие слово 'Договор'
links = page.locator("a:has-text('Договор')").all()
total = len(links)
if total == 0:
send_tg_status("❌ ОШИБКА: Договоры на экране не обнаружены. Проверьте VNC.")
return
send_tg_status(f"📜 **ЖНЕЦ ДОГОВОРОВ v2.0**\nОбнаружено в списке: {total} договоров.")
for i in range(total):
# Переполучаем список т.к. DOM меняется
current_links = page.locator("a:has-text('Договор')").all()
link = current_links[i]
name_text = link.inner_text().strip()[:100].replace('/', '_').replace(' ', '_')
print(f"[{i+1}/{total}] Вскрываем: {name_text}...")
# Клик
link.click()
page.wait_for_load_state("networkidle")
time.sleep(15)
# Папка для дела
case_dir = STORAGE_ROOT / name_text
case_dir.mkdir(parents=True, exist_ok=True)
# 1. СКРИНШОТ (Улика)
page.screenshot(path=str(case_dir / "contract_evidence.png"), full_page=True)
# 2. СКАЧИВАНИЕ
try:
# Ищем кнопку 'Скачать все' или ссылки на файлы
# В договорах часто есть вкладка 'Информация о договоре' или 'Файлы'
download_btn = page.get_by_text("Скачать все").first
if not download_btn.is_visible():
# Попробуем найти любые ссылки на скачивание
download_btn = page.locator("a[title*='Скачать'], button:has-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 / "contract_archive.zip"
download.save_as(str(zip_path))
status = "✅ ZIP + Скрин"
else:
status = "⚠️ Только скрин (кнопка скачивания не найдена)"
except Exception as e:
status = f"❌ Ошибка скачивания: {str(e)[:50]}"
# СИНХРОНИЗАЦИЯ
sync_to_nas(case_dir, name_text)
# ОТЧЕТ
bar = "" * ((i+1)*10//total) + "" * (10 - ((i+1)*10//total))
send_tg_status(f"📜 **{name_text}**\nСтатус: {status}\n\n[{bar}] {i+1}/{total}")
# НАЗАД
page.go_back()
time.sleep(10)
send_tg_status("🏁 Жатва договоров УСПЕШНО ЗАВЕРШЕНА.")
browser.close()
except Exception as e:
send_tg_status(f"🚨 КАТАСТРОФА ЖНЕЦА ДОГОВОРОВ: {str(e)}")
if __name__ == "__main__":
os.makedirs(STORAGE_ROOT, exist_ok=True)
run_harvest()