- Краулеры: smart_crawler.py, regional_crawler.py - Аудит: audit_orel_to_excel.py, audit_chukotka_to_excel.py - РКН проверка: check_rkn_registry.py, recheck_unclear_rkn.py - Отчёты: create_orel_horizontal_report.py - Обработка: process_all_hotels_embeddings.py - Документация: README.md, DB_SCHEMA_REFERENCE.md
7.5 KiB
7.5 KiB
🤖 Что делает краулер - пошаговый процесс
📋 КРАТКИЙ ОТВЕТ
Краулер делает ТОЛЬКО парсинг и сохранение в БД. Никаких эмбеддингов, векторизации или анализа!
🔄 ПОЛНЫЙ ПРОЦЕСС (шаг за шагом)
1️⃣ Получение списка отелей (get_unprocessed_hotels)
SELECT id, full_name, region_name, website_address
FROM hotel_main
WHERE website_address IS NOT NULL
AND id NOT IN (SELECT hotel_id FROM hotel_website_processed)
ORDER BY id
LIMIT 50 -- пачками по 50
Что делает:
- Берёт отели с сайтами
- Исключает уже обработанные
- Обрабатывает пачками по 50 штук
2️⃣ Краулинг сайта (crawl_hotel)
2.1. Запуск браузера Playwright
- Открывает headless браузер
- User-Agent: Mozilla/5.0 (Windows...)
- Параллельно: 5 браузеров (
MAX_CONCURRENT = 5)
2.2. Загрузка главной страницы
await page.goto(website, wait_until='domcontentloaded', timeout=20000)
- Таймаут: 20 секунд
- Ждёт загрузки DOM
2.3. Извлечение контента главной
html = await page.content() # Сырой HTML
cleaned_text = TextCleaner.clean_html(html) # Очищенный текст
TextCleaner.clean_html() делает:
- Удаляет
<script>,<style>,<meta>,<link>,<noscript> - Извлекает текст через BeautifulSoup
- Убирает лишние пробелы/переносы
- Возвращает чистый текст
2.4. Сбор внутренних ссылок
links = await page.evaluate('''() => {
return Array.from(document.querySelectorAll('a[href]'))
.map(a => a.href)
.filter(href => href && !href.startsWith('mailto:') && !href.startsWith('tel:'))
}''')
Фильтрация:
- Только внутренние ссылки (тот же домен)
- Исключает
mailto:,tel: - Убирает дубли
- Лимит: 19 ссылок (+ главная = 20 страниц)
2.5. Обход внутренних страниц
for link in internal_links[:19]: # Максимум 19 + главная = 20
page2 = await context.new_page()
await page2.goto(link, timeout=20000)
html2 = await page2.content()
text2 = TextCleaner.clean_html(html2)
# Сохраняем в pages_data
Для каждой страницы:
- Открывает новую вкладку
- Загружает страницу (20 сек таймаут)
- Извлекает HTML
- Очищает текст
- Добавляет в
pages_data[]
3️⃣ Сохранение в БД (save_to_db)
3.1. Метаданные → hotel_website_meta
INSERT INTO hotel_website_meta
(hotel_id, domain, main_url, pages_crawled, crawl_status, crawl_finished_at)
VALUES (...)
ON CONFLICT (hotel_id) DO UPDATE ...
Сохраняет:
hotel_id- UUID отеляdomain- Домен сайтаmain_url- Главный URLpages_crawled- Количество страницcrawl_status- 'completed'crawl_finished_at- Время завершения
3.2. Сырой HTML → hotel_website_raw
INSERT INTO hotel_website_raw
(hotel_id, url, html, status_code, crawled_at)
VALUES (...)
ON CONFLICT (hotel_id, url) DO UPDATE ...
Для КАЖДОЙ страницы сохраняет:
hotel_id- UUID отеляurl- URL страницыhtml- Полный сырой HTMLstatus_code- HTTP код (200, 404, etc)crawled_at- Время краулинга
3.3. Очищенный текст → hotel_website_processed
INSERT INTO hotel_website_processed
(hotel_id, url, cleaned_text, processed_at)
VALUES (...)
ON CONFLICT (hotel_id, url) DO UPDATE ...
Для КАЖДОЙ страницы сохраняет:
hotel_id- UUID отеляurl- URL страницыcleaned_text- Очищенный текст (без HTML тегов)processed_at- Время обработки
⚡ ПРОИЗВОДИТЕЛЬНОСТЬ
Настройки:
MAX_PAGES_PER_SITE = 20 # Максимум страниц с одного сайта
PAGE_TIMEOUT = 20000 # 20 секунд на загрузку страницы
MAX_CONCURRENT = 5 # 5 браузеров параллельно
BATCH_SIZE = 50 # Обрабатывать по 50 отелей
Время на 1 отель:
- Быстрый сайт (1-5 страниц): ~10-30 секунд
- Средний сайт (10-15 страниц): ~1-3 минуты
- Большой сайт (20 страниц): ~3-5 минут
- Недоступный сайт: ~20 секунд (таймаут)
Скорость обработки:
- Текущая: ~50-100 отелей/день
- Теоретическая: ~400-500 отелей/день (если все сайты быстрые)
❌ ЧТО КРАУЛЕР НЕ ДЕЛАЕТ
- ❌ НЕ создаёт эмбеддинги (векторы для поиска)
- ❌ НЕ делает чанки (разбивку на части)
- ❌ НЕ анализирует контент (нет AI/NLP)
- ❌ НЕ извлекает структурированные данные (телефоны, email, etc)
- ❌ НЕ проверяет критерии аудита
- ❌ НЕ делает скриншоты
- ❌ НЕ проверяет SSL/сертификаты
📊 ЧТО В ИТОГЕ В БД
После краулинга 1 отеля с 15 страницами:
hotel_website_meta: 1 запись
- Метаданные: домен, количество страниц, статус
hotel_website_raw: 15 записей
- 15 × полный HTML (может быть 100-500 KB каждый)
- Всего: ~1-7 MB сырых данных
hotel_website_processed: 15 записей
- 15 × очищенный текст (обычно 1-10 KB каждый)
- Всего: ~15-150 KB текста
🚀 СЛЕДУЮЩИЕ ЭТАПЫ (отдельно от краулера)
После того как краулер заполнит БД, ОТДЕЛЬНО нужно будет:
-
Создать эмбеддинги (
process_all_hotels_embeddings.py)- Разбить текст на чанки
- Создать векторы через BGE-M3
- Сохранить в
hotel_website_chunks
-
Запустить аудит (
hybrid_audit_chukotka.py)- Семантический поиск
- Регулярные выражения
- Natasha NER
- Сохранить в
hotel_audit_results
-
Интеграция с n8n
- AI Agent для анализа
- Автоматизация проверок
💡 ВЫВОД
Краулер = простой парсер:
- Открывает сайты
- Скачивает HTML
- Чистит текст
- Кладёт в БД
Всё остальное (AI, векторы, аудит) - это отдельные процессы!
Дата: 2025-10-14
Автор: Фёдор + AI Assistant