File size: 13,356 Bytes
8383076
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
---
title: AI Scraper ФИПИ
emoji: 🕷️
colorFrom: blue
colorTo: purple
sdk: docker
sdk_version: "docker"
python_version: "3.11"
app_file: app.py
pinned: false
---

# 🕷️ AI Scraper ФИПИ

Сервис для автоматического сбора заданий с сайта ФИПИ (fipi.ru) с использованием AI-анализа на основе **ruBERT**.

---

## ✨ Возможности

- 🕷️ **Автоматический парсинг** заданий с сайта ФИПИ
- 🧠 **AI-классификация** заданий через ruBERT
- 💾 **Сохранение в Supabase** с автоматическим обновлением
- 🚀 **Деплой на Hugging Face Spaces**
- 📊 **REST API** для доступа к заданиям
- 🔍 **Поиск** по заданиям
- 📈 **Статистика** и аналитика

---

## 📁 Структура

```
ai-scraper/
├── app.py                 # Основное FastAPI приложение
├── scraper.py             # Парсер сайта ФИПИ
├── rubert_client.py       # Клиент для ruBERT API
├── supabase_client.py     # Интеграция с Supabase
├── models.py              # Pydantic модели
├── requirements.txt       # Python зависимости
├── schema.sql             # SQL схема для Supabase
├── Dockerfile             # Docker конфигурация
├── hf_spaces_config.yaml  # Конфиг для Hugging Face
├── .env.example           # Шаблон переменных окружения
└── README.md              # Документация
```

---

## 🚀 Быстрый старт

### 1. Локальная разработка

```bash
cd ai-scraper

# Создайте виртуальное окружение
python -m venv venv

# Активируйте
venv\Scripts\activate  # Windows
source venv/bin/activate  # Linux/Mac

# Установите зависимости
pip install -r requirements.txt

# Скопируйте .env.example в .env (опционально)
cp .env.example .env

# Заполните .env своими ключами
# ИЛИ настройте переменные окружения в вашей системе

# Запустите сервер
uvicorn app:app --reload --host 0.0.0.0 --port 8000
```

Откройте http://localhost:8000/docs для Swagger UI.

---

## ⚙️ Переменные окружения

### Для локальной разработки

Скопируйте `.env.example` в `.env` и заполните своими значениями:

```env
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_KEY=your-service-role-key
RUBERT_URL=https://your-rubert.hf.space
FIPI_BASE_URL=https://fipi.ru
```

### Для Hugging Face Spaces

**Не нужно загружать `.env` файл!** Настройте переменные через интерфейс:

1. Откройте ваш Space
2. Перейдите в **Settings****Secrets**
3. Добавьте переменные:
   - `SUPABASE_URL`
   - `SUPABASE_SERVICE_KEY`
   - `RUBERT_URL` (опционально)
   - `FIPI_BASE_URL` (опционально)

---

## 🗄️ Настройка Supabase

### 1. Создайте проект

Перейдите на [Supabase](https://supabase.com) и создайте новый проект.

### 2. Выполните SQL скрипт

1. Откройте [SQL Editor](https://supabase.com/dashboard/project/_/sql/new)
2. Скопируйте содержимое `schema.sql`
3. Нажмите **Run**

### 3. Получите ключи

1. Перейдите в **Settings****API**
2. Скопируйте:
   - **Project URL**`SUPABASE_URL`
   - **service_role key** → `SUPABASE_SERVICE_KEY`

---

## 🧠 Настройка ruBERT

### Вариант 1: Использование существующего API

Если у вас уже есть развернутый ruBERT (как в основном проекте):

```env
RUBERT_URL=https://your-rubert-instance.hf.space
```

### Вариант 2: Развертывание ruBERT

Создайте новый Space на Hugging Face с моделью ruBERT:

1. [RuBERT от DeepPavlov](https://huggingface.co/deepvk/rubert-base-cased)
2. Используйте шаблон Gradio или FastAPI
3. Добавьте эндпоинты `/api/analyze` и `/api/embedding`

---

## 🌐 Деплой на Hugging Face Spaces

### Шаг 1: Создайте Space

1. Перейдите на [Hugging Face Spaces](https://huggingface.co/spaces)
2. Нажмите **Create new Space**
3. Заполните:
   - **Space name**: `fipi-ai-scraper`
   - **License**: MIT
   - **SDK**: Docker
   - **Visibility**: Public или Private

### Шаг 2: Загрузите файлы

```bash
# Инициализируйте git в папке ai-scraper
cd ai-scraper
git init
git add .
git commit -m "Initial commit"

# Добавьте remote вашего Space
git remote add origin https://huggingface.co/spaces/YOUR_USERNAME/fipi-ai-scraper

# Push в Space
git push -u origin main
```

### Шаг 3: Настройте переменные окружения

**Важно:** Не загружайте `.env` файл в репозиторий!

В Settings вашего Space добавьте в **Secrets**:

| Variable | Value |
|----------|-------|
| `SUPABASE_URL` | https://your-project.supabase.co |
| `SUPABASE_SERVICE_KEY` | ваш service key |
| `RUBERT_URL` | https://your-rubert.hf.space |
| `FIPI_BASE_URL` | https://fipi.ru |

⚠️ **Примечание:** Переменные окружения добавляются через интерфейс Hugging Face:
**Settings****Repository secrets****New secret**

### Шаг 4: Дождитесь деплоя

Space автоматически соберет Docker образ и запустит приложение.

---

## 📡 API Endpoints

| Метод | Эндпоинт | Описание |
|-------|----------|----------|
| GET | `/` | Информация об API |
| GET | `/api/health` | Проверка статуса сервиса |
| GET | `/api/tasks` | Получить все задания |
| GET | `/api/tasks/latest` | Последние добавленные задания |
| GET | `/api/tasks/{task_id}` | Получить задание по ID |
| GET | `/api/tasks/type/{type}` | Задания по типу |
| GET | `/api/tasks/search?q=` | Поиск заданий |
| POST | `/api/scrape` | Запустить парсинг ФИПИ |
| POST | `/api/analyze` | AI анализ существующих заданий |
| GET | `/api/stats` | Статистика по заданиям |

---

## 📝 Примеры использования

### Python

```python
import requests

BASE_URL = "https://your-space.hf.space"

# Получить последние задания
response = requests.get(f"{BASE_URL}/api/tasks/latest?limit=10")
tasks = response.json()
print(f"Найдено заданий: {len(tasks)}")

# Запустить парсинг ФИПИ
response = requests.post(f"{BASE_URL}/api/scrape")
result = response.json()
print(result["message"])

# Поиск заданий
response = requests.get(f"{BASE_URL}/api/tasks/search?q=сочинение")
tasks = response.json()

# Получить статистику
response = requests.get(f"{BASE_URL}/api/stats")
stats = response.json()
print(f"Всего заданий: {stats['total_tasks']}")
```

### cURL

```bash
# Health check
curl https://your-space.hf.space/api/health

# Получить задания
curl https://your-space.hf.space/api/tasks/latest

# Запустить скрапинг
curl -X POST https://your-space.hf.space/api/scrape \
  -H "Content-Type: application/json" \
  -d '{"subject": "russian"}'

# Поиск
curl "https://your-space.hf.space/api/tasks/search?q=ЕГЭ"
```

---

## 🔧 Конфигурация

### Переменные окружения

| Переменная | Описание | Пример |
|------------|----------|--------|
| `SUPABASE_URL` | URL проекта Supabase | `https://xxx.supabase.co` |
| `SUPABASE_SERVICE_KEY` | Service role ключ Supabase | `eyJhbG...` |
| `RUBERT_URL` | URL ruBERT API | `https://rubert.hf.space` |
| `FIPI_BASE_URL` | Базовый URL ФИПИ | `https://fipi.ru` |
| `PORT` | Порт приложения | `7860` |
| `HOST` | Хост приложения | `0.0.0.0` |

---

## 🏗️ Архитектура

```
┌─────────────────┐     ┌──────────────────┐     ┌─────────────────┐
│   FIPIScraper   │────▶│  RuBERTClient    │────▶│  SupabaseClient │
│   (BeautifulSoup)│    │  (HTTP API)      │     │  (Supabase JS)  │
└─────────────────┘     └──────────────────┘     └─────────────────┘
         │                       │                        │
         ▼                       ▼                        ▼
   fipi.ru                 ruBERT HF               Supabase DB
   (парсинг)              (AI анализ)              (хранение)
```

### Поток данных

1. **Скрапинг**: `FIPIScraper` парсит задания с fipi.ru
2. **Анализ**: `RuBERTClient` анализирует текст задания
3. **Сохранение**: `SupabaseClient` сохраняет в базу данных
4. **API**: FastAPI предоставляет REST эндпоинты

---

## 🔒 Безопасность

-**RLS (Row Level Security)** в Supabase
-**Валидация данных** через Pydantic
-**CORS** настроен для API
-**Service Key** не экспонируется на клиенте

---

## 🛠️ Решение проблем

### "Supabase не настроен"

Проверьте переменные окружения:
```bash
echo $SUPABASE_URL
echo $SUPABASE_SERVICE_KEY
```

### "RuBERT клиент не настроен"

Убедитесь, что `RUBERT_URL` указан и API доступен:
```bash
curl https://your-rubert.hf.space/api/health
```

### Ошибки при скрапинге

Сайт ФИПИ может блокировать запросы. Попробуйте:
- Изменить `User-Agent` в `scraper.py`
- Использовать прокси
- Добавить задержки между запросами

### Docker не собирается

Проверьте логи:
```bash
docker build -t fipi-scraper .
docker run -p 7860:7860 fipi-scraper
```

### Configuration error / Missing .env

**Это нормально!** Для Hugging Face Spaces:
1. Не загружайте `.env` в репозиторий
2. Настройте переменные через **Settings****Repository secrets**
3. Файл `.env.example` существует только для документации

---

## 📝 История изменений

### Март 2026 - Исправление парсера ФИПИ

**Исправленные проблемы:**
- ❌ Неверные URL-адреса (404 ошибки)
- ❌ SSL ошибки для поддоменов
- ❌ Некорректный парсинг заголовков

**Результат:**
- ✅ Найдено заданий: 0 → 12
- ✅ Все запросы возвращают 200 OK

Подробности в [FIXES.md](FIXES.md)

---

## 📊 Мониторинг

### Логи приложения

```bash
# Логи в Hugging Face Space
# Settings → Logs

# Локально
uvicorn app:app --log-level debug
```

### Метрики

- `/api/health` — статус сервисов
- `/api/stats` — статистика заданий

---

## 🤝 Интеграция с основным проектом

Этот сервис дополняет основной проект `refined-main`:

1. **Импорт заданий** из ФИПИ в базу
2. **AI-анализ** через тот же ruBERT
3. **Единая Supabase** для обоих сервисов

### Подключение

В основном проекте добавьте:

```typescript
// services/fipiTasks.ts
const FIPI_SCRAPER_URL = 'https://fipi-ai-scraper.hf.space';

export async function fetchLatestTasks(limit = 10) {
  const response = await fetch(`${FIPI_SCRAPER_URL}/api/tasks/latest?limit=${limit}`);
  return response.json();
}
```

---

## 📚 Дополнительные ресурсы

- [Документация FastAPI](https://fastapi.tiangolo.com/)
- [Документация Supabase](https://supabase.com/docs)
- [Hugging Face Spaces](https://huggingface.co/docs/hub/spaces)
- [ruBERT модель](https://huggingface.co/deepvk/rubert-base-cased)
- [ФИПИ](https://fipi.ru/)

---

## 📄 Лицензия

MIT License

---

**Последнее обновление:** Март 2026  
**Статус:** ✅ Готово к деплою