Files
hotels/test_browserless_scrape.py
Фёдор 684fada337 🚀 Full project sync: Hotels RAG & Audit System
 Major Features:
- Complete RAG system for hotel website analysis
- Hybrid audit with BGE-M3 embeddings + Natasha NER
- Universal horizontal Excel reports with dashboards
- Multi-region processing (SPb, Orel, Chukotka, Kamchatka)

📊 Completed Regions:
- Орловская область: 100% (36/36)
- Чукотский АО: 100% (4/4)
- г. Санкт-Петербург: 93% (893/960)
- Камчатский край: 87% (89/102)

🔧 Infrastructure:
- PostgreSQL with pgvector extension
- BGE-M3 embeddings API
- Browserless for web scraping
- N8N workflows for automation
- S3/Nextcloud file storage

📝 Documentation:
- Complete DB schemas
- API documentation
- Setup guides
- Status reports
2025-10-27 22:49:42 +03:00

159 lines
5.0 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.

#!/usr/bin/env python3
"""
Тест Browserless Scrape API для сравнения качества с регулярками
"""
import requests
import json
import psycopg2
from psycopg2.extras import RealDictCursor
from urllib.parse import unquote
import re
# Конфигурация БД
DB_CONFIG = {
'host': '147.45.189.234',
'port': 5432,
'database': 'default_db',
'user': 'gen_user',
'password': unquote('2~~9_%5EkVsU%3F2%5CS')
}
# Browserless API
BROWSERLESS_URL = "http://147.45.146.17:3000/function?token=9ahhnpjkchxtcho9"
def get_html_from_db():
"""Получаем HTML из БД для тестирования"""
conn = psycopg2.connect(**DB_CONFIG, cursor_factory=RealDictCursor)
cur = conn.cursor()
cur.execute("""
SELECT html, h.full_name
FROM hotel_website_raw hwr
INNER JOIN hotel_main h ON h.id = hwr.hotel_id
WHERE h.region_name = 'г. Санкт-Петербург'
AND hwr.html IS NOT NULL
LIMIT 1
""")
result = cur.fetchone()
cur.close()
conn.close()
return result['html'], result['full_name']
def clean_with_regex(html):
"""Очистка HTML регулярками (текущий метод)"""
# Удаляем script и style теги
text = re.sub(r'<script[^>]*>.*?</script>', ' ', html, flags=re.DOTALL | re.IGNORECASE)
text = re.sub(r'<style[^>]*>.*?</style>', ' ', text, flags=re.DOTALL | re.IGNORECASE)
# Удаляем все HTML теги
text = re.sub(r'<[^>]+>', ' ', text)
# Декодируем HTML entities
import html as html_module
text = html_module.unescape(text)
# Убираем лишние пробелы
text = re.sub(r'\s+', ' ', text).strip()
return text
def clean_with_browserless_scrape(html):
"""Очистка HTML через Browserless Function API"""
# JavaScript функция для извлечения текста
scrape_function = """
export default async function ({ page, context }) {
const html = context.html;
// Устанавливаем HTML в страницу
await page.setContent(html);
// Извлекаем весь текст
const text = await page.evaluate(() => {
// Удаляем script и style элементы
const scripts = document.querySelectorAll('script, style');
scripts.forEach(el => el.remove());
// Получаем весь текст
return document.body.innerText || document.body.textContent || '';
});
return {
text: text,
length: text.length
};
}
"""
payload = {
"code": scrape_function,
"context": {"html": html}
}
try:
response = requests.post(BROWSERLESS_URL, json=payload, timeout=30)
response.raise_for_status()
result = response.json()
if result and 'text' in result:
return result['text']
return ""
except Exception as e:
print(f"❌ Ошибка Browserless API: {e}")
return ""
def compare_methods():
"""Сравниваем оба метода"""
print("🔍 Получаем HTML из БД...")
html, hotel_name = get_html_from_db()
print(f"📄 Отель: {hotel_name}")
print(f"📊 Размер HTML: {len(html):,} символов")
print("\n" + "="*60)
print("🧹 МЕТОД 1: РЕГУЛЯРКИ")
print("="*60)
regex_text = clean_with_regex(html)
print(f"📏 Размер текста: {len(regex_text):,} символов")
print(f"📄 Первые 500 символов:")
print("-" * 40)
print(regex_text[:500])
print("-" * 40)
print("\n" + "="*60)
print("🌐 МЕТОД 2: BROWSERLESS SCRAPE")
print("="*60)
browserless_text = clean_with_browserless_scrape(html)
print(f"📏 Размер текста: {len(browserless_text):,} символов")
print(f"📄 Первые 500 символов:")
print("-" * 40)
print(browserless_text[:500])
print("-" * 40)
print("\n" + "="*60)
print("📊 СРАВНЕНИЕ")
print("="*60)
print(f"Регулярки: {len(regex_text):,} символов")
print(f"Browserless: {len(browserless_text):,} символов")
print(f"Разница: {len(browserless_text) - len(regex_text):,} символов")
# Анализ качества
regex_lines = regex_text.split('\n')
browserless_lines = browserless_text.split('\n')
print(f"\n📈 КАЧЕСТВО:")
print(f"Регулярки - строк: {len(regex_lines)}")
print(f"Browserless - строк: {len(browserless_lines)}")
# Подсчет пустых строк
regex_empty = sum(1 for line in regex_lines if not line.strip())
browserless_empty = sum(1 for line in browserless_lines if not line.strip())
print(f"Пустые строки (регулярки): {regex_empty}")
print(f"Пустые строки (browserless): {browserless_empty}")
if __name__ == "__main__":
compare_methods()