✨ 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
368 lines
7.9 KiB
Markdown
368 lines
7.9 KiB
Markdown
# 🕷️ 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
|
||
|
||
|
||
|
||
|