domovoy_bot/scraper_gis/services/gis_harvester/contract_harvester.py

96 lines
4.4 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_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", "matrixhasyou@192.168.10.105", 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", "matrixhasyou@192.168.10.105", 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]
# Мы уже на нужной странице (#!/agreements/citizen/...)
print("[*] Сбор списка договоров...")
page.wait_for_load_state("networkidle")
time.sleep(10)
# Находим все ссылки на просмотр договоров
# Обычно это ссылки вида #!/agreements/view/...
links = page.locator("a[href*='agreements/view/']").all()
total = len(links)
send_tg_status(f"📜 **ЖНЕТЦ ДОГОВОРОВ**\nНайдено в разделе: {total} договоров.")
for i in range(total):
# Находим ссылки заново т.к. DOM может обновиться
current_links = page.locator("a[href*='agreements/view/']").all()
link = current_links[i]
# Получаем название договора из родительской строки
row = page.locator(f"tr:has(a[href*='{link.get_attribute('href')}'])")
name_text = row.inner_text().split('\n')[0][: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)
page.screenshot(path=str(case_dir / "contract_evidence.png"), full_page=True)
# СКАЧИВАНИЕ
try:
# В договорах кнопка может называться по-другому, но часто это тоже 'Скачать все'
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 / "contract_files.zip"
download.save_as(str(zip_path))
# Синхронизация
sync_to_nas(case_dir, name_text)
status = "✅ ZIP + Скрин"
else:
sync_to_nas(case_dir, name_text)
status = "⚠️ Только скрин (кнопка скачивания не найдена)"
except Exception as e:
status = f"❌ Ошибка: {str(e)}"
send_tg_status(f"📜 **ДОГОВОР: {name_text}**\nСтатус: {status}\n[{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()