Public services and making an appointment. Live queue?

You have probably come across a situation when you need to make an appointment, but there are no free tickets. An article on how we managed to automate the waiting process using the example of obtaining a foreign passport.





After the approval of the electronic application for a passport, you must make an appointment for a personal visit in order to bring the originals of documents and take a photo. Going to public services for several days at different times, I did not find any free coupons. I didn't want to continue such a lottery.





The solution is pretty simple. When the user selects an address on the map, a request is sent that returns the available visit time. It is visible in the developer console. From there, we will learn about the URL and parameters.





def send_post(cookies):
    url = 'https://www.gosuslugi.ru/api/lk/v1/equeue/agg/slots'
    headers = {'Content-type': 'application/json;charset=UTF-8', 'Accept':'application/json', 'Cookie':cookies}
    payload = {'eserviceId':'','serviceId':[''],'organizationId':[''],'parentOrderId':'','serviceCode':'','attributes':[]}
    return post(url, data=dumps(payload), headers=headers)
      
      



A problem arises. To receive a successful response, cookies need to be added to the request. They can be copied from the same request. But they will only work for a few hours. Therefore, when we receive an error (401), we pass authorization and copy new cookies, saving them to a file. When we find free space, open the browser to this page.





Implementation required Python, Selenium and Windows Task Scheduler. Thus, we get the following main code:





from webbrowser import open as open_tab
from selenium import webdriver
from datetime import datetime
from requests import post
from json import dumps
from os import path

def main():
    response = send_post(read_cookies())
    if response.status_code == 401:
        write_cookies(get_cookies())
        write_log(' 401.  .')
        main()
        return
    elif response.status_code == 200:
        length = len(response.json()['slots'])
        if length > 0:
            write_log(' : ' + length)
            open_tab(TARGET_LINK, new=1)
        else: 
            write_log(' ')
    else:
        write_log(' {0}'.format(response.status_code))
      
      



To get cookies, using Selenium, go to the login page, find the input fields and insert a login with a password. In practice, it was not possible to log in without windowed mode. Therefore, every few hours a browser window will appear for a couple of seconds. To get the required set of cookies, go to the page where the address of the department is selected TARGET_LINK



.





def get_cookies():
    options = webdriver.ChromeOptions()
    options.add_argument('--no-sandbox')
    options.add_argument('--minimal')

    driver = webdriver.Chrome(executable_path=DRIVER_FILE, options=options)
    driver.get('https://esia.gosuslugi.ru/')
    driver.implicitly_wait(7)

    input_login = driver.find_element_by_id('login')
    input_password = driver.find_element_by_id('password')
    btn_enter = driver.find_element_by_id('loginByPwdButton')

    input_login.send_keys(LOGIN)
    input_password.send_keys(PASSWORD)
    btn_enter.click()

    driver.get(TARGET_LINK)
    cookies = driver.get_cookies()
    driver.close()
    return cookies
      
      



For a request, cookies are formatted to =;







raw_cookies = ''.join(['{}={}; '.format(i['name'], i['value']) for i in cookies])
      
      



It remains to configure the Windows Task Scheduler. .py



I did not succeed in running the script directly. Therefore, through .bat



one command python "script.py"



. Yes, this opens a console window. There are external programs that allow you to launch the console secretly.





As a result, on the third day and 240 launches around 17 o'clock, there was a free space for recording. I think we can go further and make auto-recording through subsequent requests.








All Articles