📜 ⬆️ ⬇️

We write monitoring the availability of tickets for Russian Railways

I have often heard from my acquaintances that it would be nice to see a site that will monitor the availability of free space on the Russian Railways . I thought to myself, “yes, it would be nice” and safely forgot, but the post made me remember paste copy skills, which I speak perfectly and wrap this thing in a python code. I’ll just make a reservation about what the monitoring will be about in the second part, and about this: how to go to Russian Railways from the python, what kind of mysterious sleep was written about in the previous post and how it lives on Google App Engine. So let's start:
image

At first I wrote the code, and then I thought about hosting, naturally, the site did not suggest any gain, but there was only 4 fun, therefore hosting should be free, and then I remembered App Engine . To get started, you should download the SDK . Run, specify the path to the future application:
image

In the specified working directory, create the configuration file app.yaml containing something like the following:

application: rzdzstan1 version: 1 runtime: python27 threadsafe: false api_version: 1 handlers: - url: /favicon.ico static_files: favicon.ico upload: favicon.ico - url: /.* script: web.py libraries: - name: webapp2 version: "latest" 

')
We create further in the above designated working directory, web.py and here you can already start writing copy-paste code . We will build the application on the lightweight WebApp2 . So, we write the main handlers:

 import webapp2 application = webapp2.WSGIApplication([ ('/', MainPage), ('/trains', TrainListPage), ('/suggester', SuggesterPage), ], debug=True) def main(): application.run() if __name__ == "__main__": main() 


Further, as mentioned in the basic article, we need city codes to create a query:

 def getCityId(city, s): req = 'http://pass.rzd.ru/suggester?lang=ru&stationNamePart=' + urllib.quote(city.encode('utf-8')) city = city.lower() respData = getResponse(req) rJson = json.loads(respData) for item in rJson: if item['name'].lower() == city: s.response.out.write(u': '+item['name']+' -> '+str(item['id'])+'<br>') return str(item['id']) s.response.out.write(u' : '+city+'<br>') s.response.out.write(u'    ,        :<a href="../"></a><br>') for item in rJson: s.response.out.write(item['name']+'<br>') return None 


Well, then it remains to get rid , SESSION_ID and form a final request, not forgetting that often RZD tears up connections, responds with 500 code, etc. To mask this, we will write a couple of crutches-handlers:

 def getResponse(url): good = False while not good: try: resp = opener.open(url, timeout=5) if resp.getcode() in [httplib.OK, httplib.CREATED, httplib.ACCEPTED]: good = True except (urllib2.HTTPError, HTTPException): pass return resp.read() def getResponseStub(url): r = json.loads(getResponse(url)) cnt = 0 while (r['result']!='OK' and cnt < 5): sleep(1) cnt+=1 r = json.loads(getResponse(url)) return r def getFinalRequest(): req1 = 'http://pass.rzd.ru/timetable/public/ru?STRUCTURE_ID=735&layer_id=5371&dir=0&tfl=3&checkSeats=1&\ st0='+st0+'&code0='+id0+'&dt0='+date+'&st1='+st1+'&code1='+id1+'&dt1='+date r = json.loads(getResponse(req1)) if (r['result']=='OK'): s.response.out.write(r['tp'][0]['msgList'][0]['message']) #errType s.response.out.write('<br>') return sid = str(r['SESSION_ID']) rid = str(r['rid']) req2 = 'http://pass.rzd.ru/timetable/public/ru?STRUCTURE_ID=735&layer_id=5371&dir=0&tfl=3&checkSeats=1&\ st0='+st0+'&code0='+id0+'&dt0='+date+'&st1='+st1+'&code1='+id1+'&dt1='+date+'&rid='+rid+'&SESSION_ID='+sid r = getResponseStub(req2) 


And in the resulting answer - everything is necessary for the final parsing. Now about the mysterious sleep , it has moved to the function: getResponseStub, the fact is that when we request req1 , we are thus asked to put us in the execution queue, and if we ask req2 right away , the result may not be received yet. Radioactive sources are available here to download carefully . You can try in action here and here for the quotas there are small and under the known effect will quickly end, but while this article is under pre-moderation I will try to throw some money so that the page lasts a long time. In the next part, we will attach the actual notification by email.

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


All Articles