207 lines
6.8 KiB
Markdown
207 lines
6.8 KiB
Markdown
# vprok.ru (Перекрёсток Впрок) — API Research
|
||
|
||
> Исследование проведено: 2026-03-31
|
||
> Статус: задокументированы известные endpoints + ограничения доступа
|
||
|
||
---
|
||
|
||
## ⚠️ Критичное ограничение: DDoS Guard
|
||
|
||
Сайт vprok.ru защищён DDoS Guard (ошибка #625116), который **блокирует все запросы с серверных/VPS IP-адресов**. Это означает:
|
||
|
||
- Все прямые HTTP-запросы с сервера возвращают HTML-страницу с ошибкой (HTTP 200, но не данные)
|
||
- Обход возможен только через **жилые прокси (residential proxies)** или запросы из реального браузера
|
||
- Cookie от браузера **не помогают** — блокировка на уровне IP-репутации
|
||
|
||
---
|
||
|
||
## 1. Аутентификация
|
||
|
||
### Механизм
|
||
|
||
Сайт использует **cookie-based аутентификацию** с Laravel-style remember-me токеном.
|
||
|
||
### Ключевая cookie
|
||
|
||
```
|
||
remember_xo-fo_<hash> = <long_token_value>
|
||
```
|
||
|
||
Пример имени: `remember_xo-fo_4546ffd47bc4accc5866998d8b`
|
||
|
||
Cookie устанавливается при входе с галочкой "Запомнить меня". Срок действия — длительный (обычно 1 год).
|
||
|
||
**Дополнительная cookie от DDoS Guard:**
|
||
```
|
||
ngx_s_id = <base64_encoded_session_id>
|
||
```
|
||
Устанавливается при первом посещении. Без неё запросы блокируются.
|
||
|
||
### Как получить cookie (ручной шаг — обязателен)
|
||
|
||
1. Зайти на vprok.ru в браузере, авторизоваться
|
||
2. Открыть DevTools → Application → Cookies → `www.vprok.ru`
|
||
3. Найти cookie `remember_xo-fo_*` — скопировать имя и значение
|
||
4. Также скопировать `ngx_s_id`
|
||
5. Передать в клиент
|
||
|
||
### Программная авторизация
|
||
|
||
Сайт, судя по всему, **не предоставляет публичный OAuth или API для логина**.
|
||
Авторизация идёт через форму на странице `/login` с CSRF-токеном. Теоретически:
|
||
|
||
```
|
||
POST https://www.vprok.ru/login
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
_token=<csrf_token>&login=<email>&password=<password>&remember=on
|
||
```
|
||
|
||
Но из-за DDoS Guard это работает **только с жилых IP**.
|
||
|
||
---
|
||
|
||
## 2. Поиск товаров
|
||
|
||
### Известные endpoints
|
||
|
||
| Endpoint | Метод | Описание |
|
||
|----------|-------|---------|
|
||
| `GET /catalog/search?text=<query>` | GET | HTML-страница результатов поиска |
|
||
| `GET /catalog/search?text=<query>&page=<n>` | GET | Пагинация |
|
||
|
||
### Вероятный AJAX API (требует верификации)
|
||
|
||
На основании анализа аналогичных сайтов и паттернов:
|
||
|
||
```
|
||
GET /api/v1/catalog/search?text=молоко&limit=20&page=1
|
||
Accept: application/json
|
||
Cookie: remember_xo-fo_*=...; ngx_s_id=...
|
||
```
|
||
|
||
Ожидаемая структура ответа:
|
||
```json
|
||
{
|
||
"items": [
|
||
{
|
||
"id": "12345",
|
||
"name": "Молоко 3.2% 1л",
|
||
"price": 89.90,
|
||
"oldPrice": null,
|
||
"unit": "шт",
|
||
"available": true,
|
||
"image": "https://...",
|
||
"link": "/product/catalog/moloko-1l"
|
||
}
|
||
],
|
||
"total": 150,
|
||
"page": 1,
|
||
"limit": 20
|
||
}
|
||
```
|
||
|
||
### HTML-парсинг (рабочий вариант)
|
||
|
||
Данные о товарах закодированы в атрибутах HTML-элементов:
|
||
```html
|
||
<li data-owox-product-id="12345"
|
||
data-owox-product-name="Молоко"
|
||
data-cost="89.90">
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Корзина (Basket/Cart)
|
||
|
||
### Предполагаемые endpoints
|
||
|
||
| Endpoint | Метод | Описание |
|
||
|----------|-------|---------|
|
||
| `GET /basket` | GET | HTML страница корзины |
|
||
| `POST /basket/add` | POST | Добавить товар |
|
||
| `POST /basket/update` | POST | Изменить количество |
|
||
| `POST /basket/remove` | POST | Удалить товар |
|
||
| `GET /api/v1/basket` | GET | JSON корзина (AJAX) |
|
||
|
||
### Вероятный формат добавления товара
|
||
|
||
```
|
||
POST https://www.vprok.ru/basket/add
|
||
Content-Type: application/json
|
||
X-CSRF-TOKEN: <token>
|
||
Cookie: remember_xo-fo_*=...; ngx_s_id=...
|
||
|
||
{
|
||
"product_id": "12345",
|
||
"quantity": 2
|
||
}
|
||
```
|
||
|
||
Или форм-данными:
|
||
```
|
||
product_id=12345&quantity=2&_token=<csrf>
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Заказы (Orders)
|
||
|
||
Подтверждённые endpoints (из PerekrestokOrderParser):
|
||
|
||
| Endpoint | Метод | Описание |
|
||
|----------|-------|---------|
|
||
| `GET /profile/orders/history` | GET | Список заказов (HTML) |
|
||
| `GET /profile/orders/details/<order_id>/?type=online` | GET | Детали заказа (HTML) |
|
||
|
||
Данные парсятся из HTML через BeautifulSoup.
|
||
|
||
---
|
||
|
||
## 5. Слоты доставки
|
||
|
||
Предполагаемые endpoints:
|
||
|
||
```
|
||
GET /api/v1/delivery/slots?date=2026-04-01
|
||
GET /checkout/delivery # HTML страница выбора слота
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Сессионные данные
|
||
|
||
| Cookie | Описание |
|
||
|--------|---------|
|
||
| `ngx_s_id` | DDoS Guard session ID (устанавливается автоматически) |
|
||
| `remember_xo-fo_<hash>` | Remember-me аутентификация (нужна для авторизованных запросов) |
|
||
| `XSRF-TOKEN` | CSRF защита для POST-запросов |
|
||
| `laravel_session` | PHP/Laravel сессия |
|
||
|
||
---
|
||
|
||
## 7. Как обойти DDoS Guard
|
||
|
||
### Вариант A: Жилые прокси (Residential Proxies)
|
||
```python
|
||
proxies = {
|
||
"http": "http://user:pass@residential-proxy.example.com:8080",
|
||
"https": "http://user:pass@residential-proxy.example.com:8080"
|
||
}
|
||
requests.get(url, proxies=proxies)
|
||
```
|
||
|
||
### Вариант B: Запросы с домашнего компьютера
|
||
Скрипт должен выполняться с жилого IP (домашний интернет), не с сервера/VPS.
|
||
|
||
### Вариант C: Прокидывание через браузер
|
||
Использовать selenium/playwright для получения cookies с жилого IP, затем переиспользовать в requests.
|
||
|
||
---
|
||
|
||
## 8. Источники
|
||
|
||
- [MaLevi4/PerekrestokOrderParser](https://github.com/MaLevi4/PerekrestokOrderParser) — подтверждает cookie-аутентификацию
|
||
- Прямое тестирование (2026-03-31) — подтвердило DDoS Guard блокировку
|
||
- Анализ HTML-структуры — атрибуты `data-owox-product-id` и др.
|