Загрузка данных
Вот обновленный промт. Я интегрировал все технические правки (защита Excel, сброс контекста, асинхронность, современные методы pandas, пошаговая генерация), полностью сохранив твой изначальный контекст, бизнес-логику и структуру.
Теперь его можно смело копировать и отправлять в нейросеть.
РОЛЬ И КОНТЕКСТ
Ты — Senior Python Backend Developer, QA-инженер и специалист по браузерной автоматизации (Playwright).
Твоя задача — написать production-ready код для проекта nmonitor (полуавтоматическая система мониторинга агентств недвижимости Иркутска на площадках Авито, ЦИАН, Домклик).
Стек: Python 3.11+, asyncio, Playwright (Chromium, строго асинхронный синтаксис async/await ), pandas (использовать только современные методы, без устаревшего df.append , только pd.concat ), openpyxl.
Хранилище: Локальные Excel-файлы (Master-файл companies.xlsx + отчеты в reports/ ). БД не используем.
Прокси: Не используем.
Режим браузера: headless=False (видимый браузер).
Запуск: С личного ПК пользователя, по кнопке через консольное меню.
БИЗНЕС-ЛОГИКА И АРХИТЕКТУРА
Скрипт 1: Сборщик профилей ( script1_search.py )
Запускается отдельно для каждой площадки через меню.
1.
Авито: Каталог агентств отсутствует. Поиск осуществляется путем листания объявлений вторички по Иркутску. Листать до конца, пока активна кнопка «Следующая страница». Важно: После клика на кнопку обязательно жди изменения URL (добавление ?p=X ) или появления новых блоков объявлений (через wait_for_selector или wait_for_load_state ), чтобы гарантированно не начать парсить старую страницу.
2.
ЦИАН и Домклик: Парсинг через официальные каталоги агентств.
3.
Обновление базы: При повторном запуске скрипт читает companies.xlsx . Если найденное агентство уже есть в базе (совпадение по очищенному названию), скрипт дописывает ссылку на эту площадку в существующую строку. Если компании нет — создает новую строку.
Скрипт 2: Счетчик и анализ ( script2_counter.py )
Запускается для всех площадок сразу.
1.
Читает ссылки из companies.xlsx .
2.
Переходит по каждой ссылке, парсит текущее количество объявлений.
3.
Сравнивает результаты с последним по дате отчетом в папке reports/ (определять не по имени файла, а по максимальному времени модификации os.path.getmtime ).
4.
Сохраняет новый отчет report_hh-mm_DD-MM-YYYY.xlsx .
Структура Master-файла ( companies.xlsx )
Логика статусов (колонка «Примечание»)
Профиль новый: Компания отсутствует в предыдущем отчете.
Профиль создан: В прошлом отчете было 0 , сейчас > 0 .
Профиль удалён: В прошлом отчете было > 0 , сейчас 0 .
не получено: Капча, блокировка, ошибка сети или изменение верстки.
ЖЕСТКИЕ ПРАВИЛА И АЛГОРИТМЫ
1.
Идентификация и матчинг:
Только по названию. Очистка строки: удаление кавычек, организационно-правовых форм (ООО, АО, ИП), приведение к нижнему регистру, удаление лишних пробелов.
Нечеткий поиск (fuzzy matching) не использовать. Строгое совпадение очищенных строк. Одноименные компании считаются разными, если строки не совпадают идеально после очистки.
2.
Обработка ошибок и «не получено»:
Статус не получено игнорируется при расчете дельты (сравнении с прошлым отчетом). Он не должен триггерить статус «Профиль удалён».
Если парсинг одной компании упал с ошибкой, скрипт пишет не получено , логирует ошибку в консоль и переходит к следующей компании. Цикл не прерывать.
3.
Обход капчи:
Автоматическое решение капчи не реализуется.
При обнаружении селектора капчи на странице скрипт выводит в консоль сообщение: Обнаружена капча. Решите её в браузере вручную и нажмите Enter... и вызывает input() . После нажатия Enter скрипт продолжает работу с текущей страницы.
4.
Защита от банов и утечек памяти:
User-Agent: реалистичный Chrome.
Случайные паузы между запросами: 8–15 секунд.
Случайные паузы между страницами: 10–20 секунд.
Эмуляция скроллинга страницы перед чтением DOM-дерева.
Сброс контекста: В script2_counter.py каждые 15-20 обработанных компаний полностью закрывай browser_context и создавай новый, чтобы избежать утечек памяти и накопления кэша/куки.
5.
Отказоустойчивость и безопасная запись:
Скрипт 1: Сохраняет companies.xlsx после обработки каждой страницы пагинации.
Скрипт 2: Сохраняет черновик отчета каждые 10 обработанных компаний.
Безопасная запись Excel: При любом промежуточном и финальном сохранении companies.xlsx и отчетов, сначала пиши данные во временный файл (например, temp_companies.xlsx ), а затем заменяй им оригинал через os.replace() . Это спасет базу от превращения в мусор (0 байт) при внезапном краше скрипта.
6.
CSS-селекторы:
Пиши максимально устойчивые селекторы (опирайся на data-* атрибуты, aria-label , уникальные классы).
Все селекторы выноси в config.py .
Возле каждого селектора оставляй комментарий # TODO: CHECK SELECTOR (F12) , так как верстка может измениться.
ТЕКУЩАЯ ЗАДАЧА
Напиши полный, рабочий код всех файлов проекта без сокращений и заглушек ( pass или ... ).
Файлы для генерации:
1.
config.py (URL, паузы, словарь селекторов для 3 площадок)
2.
utils.py (функции очистки названий, работы с Excel, генерации пауз)
3.
script1_search.py (классы/функции парсинга для Авито, ЦИАН, Домклик с логикой обновления строк)
4.
script2_counter.py (логика обхода профилей, сравнения с прошлым отчетом и простановки меток)
5.
main.py (консольное меню)
6.
requirements.txt
Формат ответа и ПОШАГОВАЯ ГЕНЕРАЦИЯ:
Из-за ограничения на длину ответа, не пиши весь код сразу. Работай строго по шагам:
Шаг 1: Напиши config.py , utils.py , requirements.txt и main.py . Код блоками с указанием имени файла, краткие пояснения архитектуры после кода. В конце ответа задай один вопрос по граничному кейсу, если он остался.
Шаг 2: Остановись и дождись моей команды "Дальше", чтобы написать script1_search.py .
Шаг 3: Остановись и дождись моей команды для script2_counter.py .