Проект аудита отелей: основные скрипты и документация

- Краулеры: 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
This commit is contained in:
Фёдор
2025-10-16 10:52:09 +03:00
parent 545e199389
commit 0cf3297290
105 changed files with 28743 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python3
"""
Экспорт отчета о доступности сайтов в Excel
"""
import psycopg2
from psycopg2.extras import RealDictCursor
from urllib.parse import unquote
from datetime import datetime
import pandas as pd
# Конфигурация БД
DB_CONFIG = {
'host': "147.45.189.234",
'port': 5432,
'database': "default_db",
'user': "gen_user",
'password': unquote("2~~9_%5EkVsU%3F2%5CS")
}
def export_website_status_report(region_name=None, output_file=None):
"""Экспорт отчета в Excel"""
conn = psycopg2.connect(**DB_CONFIG, cursor_factory=RealDictCursor)
cur = conn.cursor()
# Формируем запрос
where_clause = ""
params = []
if region_name:
where_clause = "WHERE region_name ILIKE %s"
params = [f'%{region_name}%']
# Получаем данные
query = f'''
SELECT
region_name as "Регион",
full_name as "Название отеля",
website_address as "Адрес сайта",
CASE website_status
WHEN 'accessible' THEN '✅ Доступен'
WHEN 'no_website' THEN '❌ Отсутствует'
WHEN 'timeout' THEN '⏱️ Таймаут'
WHEN 'connection_refused' THEN '🚫 Соединение отклонено'
WHEN 'dns_error' THEN '🔍 DNS ошибка'
WHEN 'ssl_error' THEN '🔒 SSL ошибка'
WHEN 'http_error' THEN '⚠️ HTTP ошибка'
WHEN 'invalid_url' THEN '❓ Неверный URL'
ELSE 'Не проверено'
END as "Статус сайта",
CASE
WHEN website_status = 'accessible' THEN 'Да'
WHEN website_status = 'no_website' THEN 'Нет'
ELSE 'Есть, но недоступен'
END as "Наличие сайта",
phone as "Телефон",
email as "Email",
owner_full_name as "Владелец",
owner_inn as "ИНН"
FROM hotel_main
{where_clause}
ORDER BY region_name, website_status, full_name
'''
cur.execute(query, params)
data = cur.fetchall()
# Создаем DataFrame
df = pd.DataFrame(data)
# Получаем статистику
stats_query = f'''
SELECT
region_name as "Регион",
COUNT(*) as "Всего отелей",
COUNT(CASE WHEN website_address IS NOT NULL AND website_address != '' AND website_address != '-' THEN 1 END) as "С указанным сайтом",
COUNT(CASE WHEN website_status = 'accessible' THEN 1 END) as "Сайт доступен",
COUNT(CASE WHEN website_status IN ('timeout', 'connection_refused', 'dns_error', 'ssl_error', 'http_error', 'invalid_url') THEN 1 END) as "Сайт недоступен",
COUNT(CASE WHEN website_status = 'no_website' THEN 1 END) as "Сайт отсутствует",
ROUND(COUNT(CASE WHEN website_status = 'accessible' THEN 1 END) * 100.0 / NULLIF(COUNT(CASE WHEN website_address IS NOT NULL AND website_address != '' AND website_address != '-' THEN 1 END), 0), 2) as "% доступности"
FROM hotel_main
{where_clause}
GROUP BY region_name
ORDER BY region_name
'''
cur.execute(stats_query, params)
stats_data = cur.fetchall()
stats_df = pd.DataFrame(stats_data)
cur.close()
conn.close()
# Формируем имя файла
if not output_file:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
region_suffix = f"_{region_name.replace(' ', '_')}" if region_name else "се_регионы"
output_file = f"website_status_report{region_suffix}_{timestamp}.xlsx"
# Сохраняем в Excel
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
# Лист со статистикой
stats_df.to_excel(writer, sheet_name='Статистика', index=False)
# Лист с детальными данными
df.to_excel(writer, sheet_name='Детальные данные', index=False)
# Лист с проблемными сайтами
problematic_df = df[df['Наличие сайта'] == 'Есть, но недоступен'].copy()
problematic_df.to_excel(writer, sheet_name='Недоступные сайты', index=False)
# Автоматическая ширина колонок
for sheet_name in writer.sheets:
worksheet = writer.sheets[sheet_name]
for column in worksheet.columns:
max_length = 0
column_letter = column[0].column_letter
for cell in column:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
except:
pass
adjusted_width = min(max_length + 2, 50)
worksheet.column_dimensions[column_letter].width = adjusted_width
print(f"✅ Отчет сохранен: {output_file}")
print(f"📊 Всего записей: {len(df)}")
print(f"🔴 Недоступных сайтов: {len(problematic_df)}")
return output_file
if __name__ == "__main__":
import sys
region = sys.argv[1] if len(sys.argv) > 1 else None
output = sys.argv[2] if len(sys.argv) > 2 else None
if region:
print(f"📍 Генерация отчета для региона: {region}")
else:
print("📍 Генерация отчета для всех регионов")
export_website_status_report(region, output)