📜 ⬆️ ⬇️

Monitoring of e-tickets with the help of selenium

By the will of fate, I often have to travel around Russia from city to city for short distances: I live and work in Moscow, and relatives and friends live in Kazan. Previously, train tickets had to be bought in advance, went to the train station at the ticket office, stood in queues, and the process took a lot of time, was inflexible, and everything had to be planned in advance.

In this article, I will talk about the problems when buying Russian Railways tickets and how I try to solve them by automating actions in the browser.

Introduction



Several years ago, Russian Railways began selling tickets via the Internet on its website ticket.rzd.ru , and soon electronic check-in appeared on almost all trains (it is not necessary to get a ticket purchased through the Internet in a window at the station, but you can buy a ticket online, if you want to print order form, and with him directly go to the conductor, who has a list of passengers).
')
Thus, the process began to take less time, and all its essence was reduced only to buying a ticket on the site. But tickets to popular destinations are quickly dismantled, if they are not bought in advance, and often there are simply no tickets for the train you need, not to mention such big holidays as the new year, when tickets appear on sale in 45 days, and in a few days no longer available.

Often in such cases, I just sat and updated the page in the hope that someone would pass the ticket, and I would have time to buy it. I was surprised to admit that with an intensive and long-lasting update of the ticket page I always had the opportunity to buy a ticket and leave as a result, but I had to devote a lot of time and effort to such a “brute force”.

Automation



At some point I had the idea to automate this process. Immediately, I’ll make a reservation that I automated the process of monitoring free tickets, without the purchase and prepayment stage, since Obviously, this is a dangerous undertaking.

I saw many articles on habre of selenium and its application to automate actions in the browser and decided to apply it for this task. To solve in python (it is perfect for this task) you need to install the appropriate package:

pip install selenium

The code layout can be quickly generated using the Selenium IDE (this is a plugin for Firefox), simply by performing standard actions on the page with a record of user actions pre-enabled. The plugin is available on the official website .

Then this code had to be “combed” a little and we added the parsing of the displayed information, the checks we needed, the triggering of the alarm.
The result is something like the code below:
 # coding=utf-8 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select from selenium.common.exceptions import NoSuchElementException import time, re import winsound class Rzdtemp(): def __init__(self, logger): self.logger = logger def setUp(self): self.driver = webdriver.Firefox() self.driver.implicitly_wait(30) self.base_url = "http://ticket.rzd.ru/" self.verificationErrors = [] def test_rzdtemp(self): self.logger.info('...') driver = self.driver driver.get(self.base_url + "/static/public/ticket?STRUCTURE_ID=2") driver.find_element_by_link_text("").click() self.logger.info('   ...') driver.find_element_by_id("j_username").clear() driver.find_element_by_id("j_username").send_keys("username") driver.find_element_by_id("j_password").clear() driver.find_element_by_id("j_password").send_keys("password") driver.find_element_by_id("other").click() self.logger.info('  ...') driver.find_element_by_link_text(" ").click() self.logger.info(' ...') driver.find_element_by_id("fromInput").clear() driver.find_element_by_id("fromInput").send_keys(u' ') driver.find_element_by_id("whereInput").clear() driver.find_element_by_id("whereInput").send_keys(u' ') driver.find_element_by_id("forwardDate").clear() driver.find_element_by_id("forwardDate").send_keys(u'02.09.2012') driver.find_element_by_id("ticket_button_submit").click() time.sleep(40) self.logger.info('  ...') rawhtml = driver.find_element_by_id('ajaxTrainTable').get_attribute("innerHTML") if u'' in rawhtml: self.logger.info('!!! !!!') strlist = [x.strip() for x in rawhtml.split('\n') if x.strip()!=u''] #print strlist train = '' for i,x in enumerate(strlist): if x == u'<div class="wotnumarrow">': train = strlist[i+1].replace('<span><b>','') if x == u'': #   winsound.PlaySound('alarma.ogg', winsound.SND_NOWAIT) self.logger.info(u'-%s -%s %s' % ( train, strlist[i+3].replace('<b>','').replace('</b>',''), strlist[i+5].replace('<td><span>','').replace('</span></td>',''))) elif u'' in rawhtml: self.logger.info(' ...') elif u'' in rawhtml: self.logger.info(' ...') self.logger.info('...') driver.find_element_by_link_text("").click() def tearDown(self): self.logger.info(' ...') self.driver.close() self.driver.quit() 

This code can be run in a loop at a specified interval, for example, checking tickets every 5 minutes.
The whole process of writing and debugging the code took about half an hour.
It is possible to fasten any checks to the code, for the trains, dates, places and so on that we need.
In this version, a beep sounds when it is detected that a ticket has appeared, as an alternative, you can send an email or SMS, but in this case you can simply not have time to buy a ticket.

Results


As long as there is no captcha on the site, you can safely use similar mechanisms, if it suddenly appears, you will have to invent something more complicated. Who knows, maybe in the future RZD will have something like a service with an API.
It is worth noting that, to my surprise, the tickets are dealt with quite often, and the likelihood of intercepting the just handed over ticket is very high, if you quickly complete the order. It often happened that a ticket appeared, but after filling it became clear that someone had already managed to buy it another one.
From personal experience, most tickets are dealt on the last day.
Have a good trip!

Source: https://habr.com/ru/post/174687/


All Articles