Как стать автором
Обновить

Динамика выкупа билетов РЖД в пик сезона: лето 2016, нг 2017

Наверное многие стояли у ЖД касс перед открытием в надежде приобрести билеты на желаемые места, либо пытались забронировать их через сайт в 8 утра. Какого было же удивление автора, когда летом 2015 года он подошел в 8:10 к кассе вокзала и парных мест уже не осталось в нужный поезд. После чего зародилась идея посмотреть, насколько же быстро раскупают билеты в пик сезона.

В данном исследовании получены графики выкупа билетов для популярных направлений. Показано наличие билетов от времени по типу вагонов. Ссылка на сайт в конце статьи.

image

На изображении: динамика количества свободных мест в первые часы с момента старта продаж. Поезд Москва → Круглое Поле, контрольные точки: «Москва»-«Казань».

Анализ лета 2016г — версия 1


Тестировал и отлаживал на майских каникулах, чтобы стабилизироваться к летнему пику сезона.
Направления (они же контрольные станции), которые мониторились (Анапа добавилась позже), туда\обратно:
  • МОСКВА-АНАПА
  • МОСКВА-ВОРОНЕЖ
  • МОСКВА-КАЗАНЬ
  • МОСКВА-НИЖНИЙ НОВГОРОД 1
  • МОСКВА-ПЕНЗА 1
  • МОСКВА-САМАРА
  • МОСКВА-САНКТ-ПЕТЕРБУРГ
  • МОСКВА-СОЧИ
  • МОСКВА-ЯРОСЛАВЛЬ

Каждый маршрут анализировался в течении 10-15 дней от начала продаж. Это порождало 18 «потоков» для анализа на каждый новый день.

В большинстве случаев не удавалось получить самое интересное — места с 8:00 до 8:10, упиралось в капча-решатель, инет-канал, тупняк ржд (основная причина).

В среднем, раз в секунду приходила 1 капча. Для распознавания пришлось одолжить комп помощнее. Получил точность 66%, хватило. OCR самописная (код не просите — писал год назад, один ехе уцелел).

image

10 прокси 2 месяца парсили нещадно РЖД. Дожили до конца только 6. Сначала тестировал несколько направлений на одном прокси, его забанили только через три(!) дня. Решил не рисковать, и заказал сразу 9 новых, два из которых выбыли из-за бага (они долбили сервер пару дней).

После того, как первый прокси был забанен, решено было выставить задержку, как функцию от времени начала продаж t:
t<10min => 100ms
10min > t > 2h => 1s…
Как быстро выкупались места для всех поездов в летнем сезоне:

image

Более 75% от всех билетов было раскуплено у двух поездов за первые 10 минут. Покликать можно самому, график на сайте под ссылкой «общий график».

Анализ НГ 2016-2017 — версия 2


Попытка учесть, что некоторые поезда открываются за 60 дней. Посмотреть, будет ли скачок мест с 46 на 45 день (забегая вперед — нет). Понимая, что для подключения новых маршрутов и полноты картины (кол-во дней анализа + проблема «8:00-8:10») нужно больше прокси, решил просить помощи у тех, кто ими торгует. Написал в 5-7 первых по гуглу. Бесплатно, в целях исследования. Только один поддержал — proxys.io, дали 100 прокси! Счастью не было предела, и я сделал ошибку — добавил новых направлений, увеличил время наблюдения до 30 дней. Те, что вошли в финальный отчет, на самом деле было в 2 раза больше направлений:
  • МОСКВА-САНКТ-ПЕТЕРБУРГ
  • МОСКВА-КАЗАНЬ
  • МОСКВА-СОЧИ
  • МОСКВА-НИЖНИЙ НОВГОРОД 1
  • МОСКВА-ЯРОСЛАВЛЬ
  • МОСКВА-ВОРОНЕЖ
  • МОСКВА-ПЕТРОЗАВОДСК-ПАСС
  • МОСКВА-МИНСК
  • МОСКВА-САМАРА
  • МОСКВА-ХЕЛЬСИНКИ

Два современных 4-ядерных компа обрабатывали запросы, но задыхались от капчи, забивался домашний инет канал. Но выяснил я это не сразу. В результате самое ценное, 8ч утра, почти все парсеры протупили. Решить эту проблему не было ни времени, ни оборудования. Между версиями, на скорую руку, рефакторил код и подыскивал инфраструктуру, но дальнейшие исправления требовали значительных сил.

Техническая часть


Версия 1: прокси squid3 на 10 vps под линукс: 1000р в месяц, 3-4 месяца работы. БД для парсеров — mongoDB(конечная база вышла на 1гиг по вагонам), сервер OCR — c#, с++, teseract, openCV. Парсеры на c#, логирование ошибок в slack через log4net. Анализатор, молотилка — node.js(искал задачу под es6). Вэбсайт для отладки — express, далее для git-pages — gulp.
Версия 2: добавлен прокси-switcher(их же теперь 100 штук) и аккаунт-switcher(в конечном счете я обошёлся всего двумя аккаунтами). Второй OCR-сервер, round-robin балансер для капчи.

Описание особых ситуаций. Можно пропустить, если разобрались, как читать график
  1. Долго никто не покупал (рисунок в п. 2а): программа сохраняет лишь изменения мест, так что если кто-то между проверкой купил 100 билетов, и продал 100, вы не увидите эти изменения — будет горизонталь.
  2. Малое время анализа на крайних датах. Как видим ниже, маршрут анализировался всего 3 дня. а) В данном случае парсер был включен слишком поздно и задел только эти дни (май, 12 — примерно 15 дней от старта продаж. Анализировались первые 10-15 дней для лета 2016):

    image2a

    б) Возьмем с другой стороны, момент окончательной остановки парсера, как только он начал анализировать новый день. Так же видно, что данный поезд уже был открыт за 60 дней — при увеличении графика видно начало сбора — 7:58:

    image2b
  3. Ситуация, когда не было данных по вагонам, но затем «подцепили» (горизонтальная черта означает, что от начала продаж до перпендикуляра не было никакой информации о вагонах — вероятнее всего их добавили. Это сделано, чтобы не потерять полученную информацию о других местах, допустим, плац либо купе):

    image3a

    Другой вариант (могу предположить, сперва появилось 50 мест в плаце, в среду 11. Далее сразу добавили/открыли еще 160 мест плаца):

    image3b

  4. Никто не покупал билеты от первоначального анализа до окончания мониторинга, либо парсер(поток) почти сразу отрубился (умер):

    image4

  5. Непонятное поведение с отрицательным количеством мест, явление довольно редкое и я по началу думал это скрыть, но было бы не честно. Видимо чего-то не учёл, за разумное время не смог определить и восстановить картину. Списываю на пропажу записи нескольких дифов в базу, из-за которых алгоритм склейки начудил:

    image5

  6. Пустые дни, например: ЯРОСЛАВЛЬ-МОСКВА#17.06.2016. Вариантов несколько: либо нет поездов, либо нагрузка на сервер была большой и пришлось вырубать несколько маршрутов, чтобы дать другим процессам отработать. Несколько дней не работал OCR-сервер, несколько головной.

Нельзя учесть всё сразу или ждите версию-3
Прокси периодически банят, инет отрубается, проблемы у хостера… Было пару дней, когда я забивал на систему/уезжал/переключался. Иногда не хватало озу и парсинг обрубался. Я не могу гарантировать 100% достоверности данных, но я проверил по сайту ржд 20 случайных графиков на последнем этапе разработки. Да, вероятно что-то не учел, это пойдёт в версию-3.

Благодарности
Выражаю благодарность сервису покупки прокси proxys.io, который безвозмездно выделил на вторую часть 100 штук IP4 адресов на 2 месяца. Без их помощи не было бы анализа 2017НГ. Советую, очень оперативная тех поддержка и хорошее отношение к клиентам.

Результат оформлен в виде сайта. Следует учесть, что акцент делался на середину лета и новый год. Не стоит устанавливать календарь на границы, там парсер только начинал собирать информацию, либо резко был отключен. Это больше отладочная информация.

Сайт хостится через гитхаб github.com/rzdbuy/rzdbuy-site, принимаю пул-реквесты багов вёрстки:

Предупреждение: При просмотре конкретного направления подробно(с календарем), оно подгружается целиком за весь период, что занимает время на обработку и расходует много трафика — до 7МБ. Не заходите с мобилок и плантшетов.

[ Лето 2016 ]
[ Новый год 2016-2017 ]
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.