2
0
Fork
You've already forked porter
0
No description
  • Go 84.4%
  • Go Template 15.3%
  • Makefile 0.3%
2026年07月08日 18:52:53 +03:00
migrations Деактивация задач 2024年08月14日 12:56:39 +03:00
modules Новые данные 2025年03月18日 08:50:35 +03:00
templates Деактивация задач 2024年08月14日 12:56:39 +03:00
.gitignore Скачивание архивов 2024年08月19日 11:22:21 +03:00
config.yaml.example Makefile и конфиг 2025年04月06日 22:01:03 +03:00
go.mod Новый тип 2024年12月05日 11:56:40 +03:00
go.sum Загрузка задач 2024年08月13日 10:38:45 +03:00
main.go Новый запрос и пр 2025年02月27日 12:13:39 +03:00
Makefile Makefile и конфиг 2025年04月06日 22:01:03 +03:00
README.md Readme 2026年07月08日 18:52:53 +03:00

Porter — парсер тарифов доставки Porter.in

Веб-приложение на Go для автоматического сбора и мониторинга цен на доставку через сервис Porter.in. Приложение регулярно запрашивает котировки стоимости доставки по заданным маршрутам, сохраняет историю цен в SQLite и предоставляет веб-интерфейс для управления заказами и выгрузки данных.

Функциональность

  • Автоматический парсинг цен — каждые N минут (по умолчанию 10) отправляет запросы к API Porter.in для получения актуальных цен по всем активным маршрутам
  • Поддержка двух SOCKS5-прокси — при каждом обходе случайным образом выбирается один из двух прокси для распределения нагрузки
  • График работы по IST — парсер работает только с 7:00 до 23:00 по индийскому времени (Asia/Kolkata)
  • Веб-интерфейс на Bootstrap 5:
    • Загрузка маршрутов через XLSX-файл
    • Настройка интервала опроса
    • Скачивание CSV-файлов за выбранный период (архивом ZIP)
    • Деактивация всех маршрутов
    • Отображение времени последнего обхода
  • Миграции БД — автоматическое создание и обновление схемы SQLite
  • Генерация ежедневных CSV — по окончании каждого цикла формируется CSV-файл с данными за текущий день

Установка и запуск

Требования

  • Go 1.22.5 или новее

Сборка

make build
# или
go build ./main.go

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

Скопируйте файл конфигурации и отредактируйте под себя:

cp config.yaml.example config.yaml

Параметры конфигурации:

port:3000# Порт веб-сервераroot:/path/to/app/root/# Путь к корневой директории приложенияproxy1:socks5://127.0.0.1:8080 # Первый SOCKS5-проксиproxy2:socks5://127.0.0.1:8080 # Второй SOCKS5-прокси

Поле root должно указывать на директорию, содержащую поддиректории migrations/, templates/ и csv/.

Миграции БД

Перед первым запуском выполните миграции:

./main -cfg /path/to/config.yaml -m

Запуск

make run
# или
go build ./main.go && ./main -cfg /path/to/config.yaml

Флаг -cfg указывает путь к конфигурационному файлу (по умолчанию ./config.yaml).

Использование

Все действия выполняются на главной странице /.

Загрузка маршрутов

Подготовьте XLSX-файл со следующими колонками:

  1. Координаты точки отправления (широта,долгота)
  2. Координаты точки назначения (широта,долгота)

Первая строка считается заголовком и пропускается. Координаты в ячейках указываются через запятую (например, 12.9716,77.5946). Выберите файл и нажмите «Загрузить».

Настройка интервала опроса

Введите количество минут в поле «Интервал обхода (минуты)» и нажмите «Установить».

Скачивание данных

Выберите начальную и конечную дату, нажмите «Скачать» — будет сгенерирован ZIP-архив с CSV-файлами за каждый день указанного диапазона.

Деактивация маршрутов

Нажмите «Деактивировать всё» — все активные заказы будут помечены как неактивные, и парсер перестанет по ним собирать данные.

Формат CSV

Сгенерированные CSV-файлы содержат BOM (UTF-8) и следующие колонки:

Колонка Описание
Время обхода Дата и время сбора данных (IST)
Координаты от Широта и долгота точки отправления
Координаты до Широта и долгота точки назначения
Транспорт ID типа транспортного средства
Цена Стоимость доставки (в индийских рупиях)
Время Расчётное время доставки (в минутах)

В CSV попадают только данные, собранные в интервале с 7:00 до 23:00 IST, и только для транспорта с ID: 1, 91, 97, 109.

Архитектура проекта

porter/
├── main.go # Точка входа: CLI, инициализация, запуск
├── go.mod / go.sum # Модули Go и зависимости
├── Makefile # Сборка и запуск
├── config.yaml.example # Пример конфигурации
├── migrations/ # SQL-миграции
│ ├── 10_create_config_table.up.sql
│ ├── 20_create_orders_table.up.sql
│ └── 30_create_datas_table.up.sql
├── modules/
│ ├── config/config.go # Загрузка YAML-конфигурации
│ ├── database/database.go # Работа с SQLite (CRUD)
│ ├── migrate/migrate.go # Применение миграций
│ ├── parser/parser.go # Парсер API Porter.in
│ ├── structures/structures.go # Структуры данных
│ └── web/
│ ├── web.go # Маршруты Gin
│ └── controller.go # Обработчики HTTP
└── templates/
 └── index.tmpl # Шаблон веб-страницы

Ключевые модули

Модуль Назначение
modules/config Чтение YAML-конфига через cleanenv
modules/database Обёртка над SQLite (mattn/go-sqlite3) с транзакциями
modules/migrate Накат миграций через golang-migrate/migrate
modules/parser Цикл парсинга: запросы к API Porter.in через SOCKS5, запись в БД, генерация CSV
modules/structures Все Go-структуры: Order, Data, Answer и пр.
modules/web Gin-сервер: маршруты и HTML-шаблон

Поток работы

  1. При запуске открывается SQLite-БД (database.db) и парсятся URL прокси
  2. Запускается горутина парсера с бесконечным циклом
  3. В цикле:
    • Проверяется время (только 7:00–23:00 IST)
    • Читается интервал опроса из таблицы config
    • Выбираются все активные заказы из таблицы orders
    • Для каждого заказа через случайный прокси отправляется POST-запрос к https://porter.in/customers/on_demand/quotations
    • Ответ содержит список доступных транспортных средств и цен
    • Все собранные данные пачкой записываются в таблицу datas
    • Формируется CSV-файл за текущий день
  4. Параллельно запускается веб-сервер Gin для взаимодействия с пользователем

Зависимости

База данных

Файл database.db создаётся автоматически в корневой директории.

Таблицы

Таблица Назначение
config Хранит настройки (ключ-значение), например, интервал опроса
orders Список маршрутов с координатами и флагом активности
datas История цен по каждому заказу с привязкой по order_id

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

Флаг -cfg можно опустить — по умолчанию конфиг читается из ./config.yaml.