test1 / update_data.py
vydrking's picture
Upload 19 files
53fe915 verified
import json
import os
import sys
from typing import List, Dict
from scraper.html_scraper import HTMLScraper
from scraper.pdf_parser import PDFParser
from scraper.normalize import DataNormalizer
from knowledge_base import KnowledgeBase
from retriever import Retriever
def update_data_async():
try:
print('Начинаем обновление данных с сайтов ITMO...')
# 1. Скрапинг страниц программ
scraper = HTMLScraper()
programs = scraper.scrape_programs()
scraper.save_programs(programs)
if not programs:
print('Не удалось получить данные программ, используем тестовые данные')
knowledge_base = KnowledgeBase()
retriever = Retriever()
retriever.build_or_load_index(knowledge_base.courses)
return
# 2. Скачивание и парсинг PDF
pdf_parser = PDFParser()
all_courses = []
for program_id, program in programs.items():
print(f'\nОбработка программы: {program["title"]}')
if not program.get('pdf_links'):
print(f'PDF ссылки не найдены для программы {program_id}')
continue
for pdf_link in program['pdf_links']:
try:
filename = pdf_link['filename']
url = pdf_link['url']
print(f'Скачивание PDF: {filename}')
local_path = pdf_parser.download_pdf(url, filename)
if local_path:
print(f'Парсинг PDF: {filename}')
courses = pdf_parser.parse_pdf(local_path, program_id)
all_courses.extend(courses)
print(f'Извлечено курсов из {filename}: {len(courses)}')
else:
print(f'Не удалось скачать PDF: {filename}')
except Exception as e:
print(f'Ошибка обработки PDF {pdf_link["filename"]}: {e}')
# 3. Нормализация данных
if all_courses:
print(f'\nНормализация {len(all_courses)} курсов...')
normalizer = DataNormalizer()
normalized_courses = normalizer.normalize_courses(all_courses)
enriched_courses = normalizer.enrich_courses(normalized_courses)
# Сохранение курсов
save_courses(enriched_courses)
# 4. Создание индекса
print('Создание индекса...')
retriever = Retriever()
retriever.build_or_load_index(enriched_courses)
# Статистика
stats = normalizer.get_statistics(enriched_courses)
print(f'Статистика: {stats}')
print('Обновление данных завершено успешно!')
else:
print('Не удалось извлечь курсы из PDF, используем тестовые данные')
knowledge_base = KnowledgeBase()
retriever = Retriever()
retriever.build_or_load_index(knowledge_base.courses)
except Exception as e:
print(f'Ошибка обновления данных: {e}')
print('Используем тестовые данные...')
knowledge_base = KnowledgeBase()
retriever = Retriever()
retriever.build_or_load_index(knowledge_base.courses)
def save_courses(courses: List[Dict], output_path: str = 'data/processed/courses.json'):
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(courses, f, ensure_ascii=False, indent=2)
print(f'Курсы сохранены в {output_path}')
def check_data_exists() -> bool:
programs_path = 'data/processed/programs.json'
courses_path = 'data/processed/courses.json'
index_path = 'data/index/index.faiss'
return all(os.path.exists(path) for path in [programs_path, courses_path, index_path])
def load_existing_data() -> tuple[Dict, List[Dict]]:
programs = {}
courses = []
try:
with open('data/processed/programs.json', 'r', encoding='utf-8') as f:
programs = json.load(f)
except FileNotFoundError:
print('Файл programs.json не найден')
try:
with open('data/processed/courses.json', 'r', encoding='utf-8') as f:
courses = json.load(f)
except FileNotFoundError:
print('Файл courses.json не найден')
return programs, courses
def check_for_updates() -> bool:
"""Проверяет наличие обновлений на сайтах ITMO"""
try:
scraper = HTMLScraper()
programs, _ = load_existing_data()
if not programs:
return True # Нет данных, нужно обновление
updates = scraper.check_updates(programs)
return len(updates) > 0
except Exception as e:
print(f'Ошибка проверки обновлений: {e}')
return False
def initialize_data():
if check_data_exists():
print('Данные уже существуют, проверяем обновления...')
if check_for_updates():
print('Обнаружены обновления, запускаем обновление данных...')
update_data_async()
else:
print('Обновлений не найдено, загружаем существующие данные...')
programs, courses = load_existing_data()
if courses:
retriever = Retriever()
retriever.build_or_load_index(courses)
print(f'Загружено {len(courses)} курсов')
else:
print('Курсы не найдены, запускаем обновление...')
update_data_async()
else:
print('Данные не найдены, запускаем первичное обновление...')
update_data_async()
def main():
if len(sys.argv) > 1:
if sys.argv[1] == '--force':
print('Принудительное обновление данных...')
update_data_async()
elif sys.argv[1] == '--check':
print('Проверка обновлений...')
if check_for_updates():
print('Обнаружены обновления')
else:
print('Обновлений не найдено')
else:
print('Использование: python update_data.py [--force|--check]')
else:
initialize_data()
if __name__ == '__main__':
main()