File size: 7,293 Bytes
5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 53fe915 5071500 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
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()
|