🚀 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
This commit is contained in:
367
PARSER_API_README.md
Normal file
367
PARSER_API_README.md
Normal file
@@ -0,0 +1,367 @@
|
||||
# 🕷️ Universal Parser API
|
||||
|
||||
Универсальный API для парсинга любых сайтов с обходом защит (Cloudflare, WAF, антибот систем).
|
||||
|
||||
## 🚀 Возможности
|
||||
|
||||
- ✅ Обход Cloudflare, WAF, антибот систем
|
||||
- ✅ Рендеринг JavaScript (React, Vue, Angular)
|
||||
- ✅ Извлечение текста и HTML
|
||||
- ✅ Парсинг ссылок
|
||||
- ✅ Скриншоты страниц
|
||||
- ✅ API ключ для безопасности
|
||||
- ✅ Асинхронная обработка
|
||||
|
||||
## 📦 Установка
|
||||
|
||||
```bash
|
||||
# Установка зависимостей
|
||||
pip3 install --break-system-packages fastapi uvicorn playwright playwright-stealth
|
||||
|
||||
# Установка браузеров Playwright
|
||||
playwright install chromium
|
||||
```
|
||||
|
||||
## 🔧 Запуск
|
||||
|
||||
```bash
|
||||
# Запуск API сервера
|
||||
python3 universal_parser_api.py
|
||||
|
||||
# Сервер запустится на http://localhost:8003
|
||||
# Документация: http://localhost:8003/docs
|
||||
```
|
||||
|
||||
## 🔑 API Ключ
|
||||
|
||||
```
|
||||
X-API-Key: parser_2025_secret_key_a8f3d9c1b4e7
|
||||
```
|
||||
|
||||
⚠️ **В продакшене:** храни ключ в `.env` файле!
|
||||
|
||||
## 📡 Endpoints
|
||||
|
||||
### 1. POST /parse
|
||||
|
||||
Парсинг страницы с обходом защит.
|
||||
|
||||
**Параметры запроса:**
|
||||
|
||||
```json
|
||||
{
|
||||
"url": "https://example.com",
|
||||
"wait_seconds": 3, // Время ожидания после загрузки
|
||||
"extract_links": false, // Извлечь все ссылки
|
||||
"screenshot": false, // Сделать скриншот
|
||||
"javascript_enabled": true, // Включить JS
|
||||
"user_agent": null // Кастомный User-Agent (опционально)
|
||||
}
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"url": "https://example.com",
|
||||
"status_code": 200,
|
||||
"title": "Example Domain",
|
||||
"html": "<html>...</html>",
|
||||
"text": "Example Domain\nThis domain is for...",
|
||||
"text_length": 1234,
|
||||
"links": ["https://...", "..."],
|
||||
"screenshot_base64": null,
|
||||
"parsing_time": 2.45,
|
||||
"timestamp": "2025-10-17T16:30:00",
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
### 2. GET /health
|
||||
|
||||
Проверка статуса API.
|
||||
|
||||
**Ответ:**
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"version": "1.0.0",
|
||||
"timestamp": "2025-10-17T16:30:00"
|
||||
}
|
||||
```
|
||||
|
||||
## 💻 Примеры использования
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
API_URL = "http://localhost:8003"
|
||||
API_KEY = "parser_2025_secret_key_a8f3d9c1b4e7"
|
||||
|
||||
def parse_page(url):
|
||||
headers = {
|
||||
"X-API-Key": API_KEY,
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
payload = {
|
||||
"url": url,
|
||||
"wait_seconds": 5,
|
||||
"extract_links": True
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
f"{API_URL}/parse",
|
||||
headers=headers,
|
||||
json=payload
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"Статус: {data['status_code']}")
|
||||
print(f"Title: {data['title']}")
|
||||
print(f"Текст: {data['text'][:500]}")
|
||||
|
||||
return response.json()
|
||||
|
||||
# Использование
|
||||
result = parse_page("https://mos-sud.ru/...")
|
||||
```
|
||||
|
||||
### cURL
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8003/parse" \
|
||||
-H "X-API-Key: parser_2025_secret_key_a8f3d9c1b4e7" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"url": "https://example.com",
|
||||
"wait_seconds": 3,
|
||||
"extract_links": true
|
||||
}'
|
||||
```
|
||||
|
||||
### JavaScript
|
||||
|
||||
```javascript
|
||||
const parseUrl = async (url) => {
|
||||
const response = await fetch('http://localhost:8003/parse', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-API-Key': 'parser_2025_secret_key_a8f3d9c1b4e7',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
url: url,
|
||||
wait_seconds: 3,
|
||||
extract_links: true
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
console.log('Статус:', data.status_code);
|
||||
console.log('Title:', data.title);
|
||||
console.log('Текст:', data.text.substring(0, 500));
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
// Использование
|
||||
parseUrl('https://example.com');
|
||||
```
|
||||
|
||||
### PHP
|
||||
|
||||
```php
|
||||
<?php
|
||||
$url = "http://localhost:8003/parse";
|
||||
$api_key = "parser_2025_secret_key_a8f3d9c1b4e7";
|
||||
|
||||
$data = [
|
||||
"url" => "https://example.com",
|
||||
"wait_seconds" => 3,
|
||||
"extract_links" => true
|
||||
];
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"X-API-Key: $api_key",
|
||||
"Content-Type: application/json"
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$result = json_decode($response, true);
|
||||
|
||||
echo "Статус: " . $result['status_code'] . "\n";
|
||||
echo "Title: " . $result['title'] . "\n";
|
||||
|
||||
curl_close($ch);
|
||||
?>
|
||||
```
|
||||
|
||||
## 🧪 Тестирование
|
||||
|
||||
```bash
|
||||
# Запустить тестовый скрипт
|
||||
python3 test_parser_api.py
|
||||
```
|
||||
|
||||
## 🔒 Безопасность
|
||||
|
||||
1. **API ключ в .env:**
|
||||
|
||||
```bash
|
||||
# .env
|
||||
PARSER_API_KEY=parser_2025_secret_key_a8f3d9c1b4e7
|
||||
```
|
||||
|
||||
```python
|
||||
# В коде
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
API_KEY = os.getenv("PARSER_API_KEY")
|
||||
```
|
||||
|
||||
2. **Rate limiting** (добавить если нужно):
|
||||
|
||||
```bash
|
||||
pip install slowapi
|
||||
```
|
||||
|
||||
3. **HTTPS** (для продакшена):
|
||||
|
||||
```bash
|
||||
uvicorn universal_parser_api:app --host 0.0.0.0 --port 8003 --ssl-keyfile key.pem --ssl-certfile cert.pem
|
||||
```
|
||||
|
||||
## 🎯 Use Cases
|
||||
|
||||
### 1. Парсинг судебных сайтов
|
||||
|
||||
```python
|
||||
result = parse_page("https://mos-sud.ru/312/cases/...")
|
||||
case_number = extract_case_number(result['text'])
|
||||
```
|
||||
|
||||
### 2. Мониторинг сайтов
|
||||
|
||||
```python
|
||||
# Проверка изменений на сайте каждые 5 минут
|
||||
import schedule
|
||||
|
||||
def check_website():
|
||||
result = parse_page("https://target-site.com")
|
||||
if "ВАЖНОЕ ОБНОВЛЕНИЕ" in result['text']:
|
||||
send_notification()
|
||||
|
||||
schedule.every(5).minutes.do(check_website)
|
||||
```
|
||||
|
||||
### 3. Сбор данных
|
||||
|
||||
```python
|
||||
# Парсинг списка отелей
|
||||
result = parse_page("https://booking-site.com", extract_links=True)
|
||||
hotel_links = [link for link in result['links'] if '/hotel/' in link]
|
||||
|
||||
for link in hotel_links:
|
||||
hotel_data = parse_page(link)
|
||||
save_to_database(hotel_data)
|
||||
```
|
||||
|
||||
## 📊 Производительность
|
||||
|
||||
- ⚡ Скорость: 2-5 секунд на страницу
|
||||
- 🔄 Параллельность: Поддерживает множественные запросы
|
||||
- 💾 Память: ~200MB на один браузер
|
||||
|
||||
## 🐛 Отладка
|
||||
|
||||
Логи сохраняются в `parser_api.log`:
|
||||
|
||||
```bash
|
||||
tail -f parser_api.log
|
||||
```
|
||||
|
||||
## 🚀 Production
|
||||
|
||||
### Запуск через systemd
|
||||
|
||||
```ini
|
||||
# /etc/systemd/system/parser-api.service
|
||||
[Unit]
|
||||
Description=Universal Parser API
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/path/to/project
|
||||
ExecStart=/usr/bin/python3 universal_parser_api.py
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl enable parser-api
|
||||
sudo systemctl start parser-api
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.12-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
wget \
|
||||
gnupg \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
RUN playwright install --with-deps chromium
|
||||
|
||||
COPY universal_parser_api.py .
|
||||
|
||||
EXPOSE 8003
|
||||
|
||||
CMD ["python3", "universal_parser_api.py"]
|
||||
```
|
||||
|
||||
## 📝 Примечания
|
||||
|
||||
- ⚠️ Соблюдай robots.txt и ToS сайтов
|
||||
- ⚠️ Используй rate limiting для больших объёмов
|
||||
- ⚠️ Некоторые сайты могут всё равно блокировать (требуется прокси)
|
||||
|
||||
## 🆘 Поддержка
|
||||
|
||||
Если API не работает:
|
||||
|
||||
1. Проверь логи: `tail -f parser_api.log`
|
||||
2. Проверь статус: `curl http://localhost:8003/health`
|
||||
3. Проверь API ключ
|
||||
4. Проверь порт 8003 (не занят ли)
|
||||
|
||||
---
|
||||
|
||||
**Версия:** 1.0.0
|
||||
**Дата:** 17.10.2025
|
||||
**Автор:** Your Team
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user