Загрузка данных
"""
Мониторинг новых заказов на Profi.ru -> уведомления в Telegram.
Установка:
pip install playwright requests
playwright install chromium
Первый запуск (войти в аккаунт вручную, сессия сохранится):
python profi_watcher.py login
Обычная работа:
python profi_watcher.py
"""
import asyncio
import hashlib
import json
import os
import sys
import requests
from playwright.async_api import async_playwright
# ---------- НАСТРОЙКИ ----------
BOT_TOKEN = "ВАШ_ТОКЕН_ОТ_BOTFATHER"
CHAT_ID = "ВАШ_CHAT_ID"
# Откройте в браузере ленту заказов исполнителя и вставьте сюда её адрес
FEED_URL = "https://profi.ru/ВСТАВЬТЕ_АДРЕС_ЛЕНТЫ_ЗАКАЗОВ"
# CSS-селектор карточки заказа. Подберём вместе по реальной странице
# (ПКМ на заказе -> «Просмотреть код»). Пока стоит общий вариант.
ITEM_SELECTOR = "a[href*='order']"
KEYWORDS = ["снегозадерж", "снегоудерж", "снегозащит", "кровл"]
CHECK_EVERY_SEC = 240 # раз в 4 минуты, чаще не стоит
STATE_FILE = "profi_session.json"
SEEN_FILE = "seen.json"
# --------------------------------
def load_seen():
if os.path.exists(SEEN_FILE):
with open(SEEN_FILE, encoding="utf-8") as f:
return set(json.load(f))
return set()
def save_seen(seen):
with open(SEEN_FILE, "w", encoding="utf-8") as f:
json.dump(sorted(seen), f)
def send_telegram(text):
url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
try:
requests.post(
url,
data={"chat_id": CHAT_ID, "text": text[:4000]},
timeout=15,
)
except requests.RequestException as e:
print("Ошибка Telegram:", e)
async def login():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
context = await browser.new_context()
page = await context.new_page()
await page.goto("https://profi.ru")
input("Войдите в аккаунт в открывшемся окне и нажмите Enter здесь...")
await context.storage_state(path=STATE_FILE)
await browser.close()
print("Сессия сохранена.")
async def check_once(context, seen):
page = await context.new_page()
try:
await page.goto(FEED_URL, wait_until="networkidle", timeout=60000)
items = await page.query_selector_all(ITEM_SELECTOR)
for item in items:
text = (await item.inner_text()).strip()
href = await item.get_attribute("href") or ""
if not text:
continue
uid = hashlib.md5((href + text[:200]).encode()).hexdigest()
if uid in seen:
continue
seen.add(uid)
if any(k in text.lower() for k in KEYWORDS):
link = href if href.startswith("http") else "https://profi.ru" + href
send_telegram(f"🔔 Новый заказ:\n\n{text[:700]}\n\n{link}")
save_seen(seen)
finally:
await page.close()
async def main():
if not os.path.exists(STATE_FILE):
print("Сначала запустите: python profi_watcher.py login")
return
seen = load_seen()
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
context = await browser.new_context(storage_state=STATE_FILE)
send_telegram("✅ Мониторинг Profi.ru запущен")
while True:
try:
await check_once(context, seen)
except Exception as e:
print("Ошибка проверки:", e)
await asyncio.sleep(CHECK_EVERY_SEC)
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "login":
asyncio.run(login())
else:
asyncio.run(main())