CoderCastrov logo
CoderCastrov
Парсер

Как наука о данных помогла мне обновить мой паспорт

Как наука о данных помогла мне обновить мой паспорт
просмотров
4 мин чтение
#Парсер
Table Of Content

Немного предыстории перед этой историей: как это обычно бывает у аргентинцев, у меня есть второе гражданство - итальянское, которое я унаследовал от своих родителей. Это двойное гражданство очень помогло мне поступить на магистратуру по науке о данных и обществу за рубежом в 2021 и 2022 годах. Благодаря этому привилегию мне не нужна была виза, стоимость обучения была намного ниже (в то время около €12 тыс. для иностранных студентов и всего €2 тыс. для граждан ЕС), и у меня был доступ к другим льготам, таким как студенческие займы.

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

Итальянское посольство в Нидерландах предлагает очень ограниченное количество ежедневных приемов для обновления паспортов, и, как и ожидалось, я не смог получить ни одного приема до даты истечения срока действия. Самый ранний доступный прием был в марте следующего года. Хотя обновление паспорта не было жизненно важным, мне нужен был паспорт для многих процедур и для свободного перемещения по Европе.

Прежде чем погрузиться в отчаяние, мне пришла в голову идея воспользоваться тем, что я узнал в магистратуре и создать инструмент, который поможет мне получить более ранний прием. Учитывая, что система работала подобно обычной онлайн-системе записи на прием, и предполагая, что если кто-то отменит свой прием, он автоматически (или через определенный интервал времени) будет отображаться как доступный, я приступил к проекту.

Задача бота была очень простой: через определенный промежуток времени он открывал веб-браузер, переходил на страницу посольства, входил в систему с помощью моих учетных данных, проверял, есть ли доступные приемы, и бронировал их.

Программирование всего пути, которым должен следовать бот, было довольно простым, но при попытке запустить его возникли проблемы с обнаружением автоматизации и капчей. Поэтому я решил применить некоторые стратегии, такие как случайное время ожидания между каждым вводом букв моего имени пользователя и пароля, а также прокрутка страницы, чтобы имитировать более человеческое поведение. Кроме того, сам процесс бронирования оказался немного сложнее, поэтому я просто позволил боту проверять наличие доступных приемов и, в случае положительного результата, уведомлять меня, чтобы я мог вручную забронировать прием. И, удивительно, это сработало!

Бот был создан на языке Python с использованием Selenium в качестве пакета для парсинга, поскольку в то время он был мне наиболее знакомым, и мне нужно было взаимодействовать с браузером. Код этого бота можно найти на моем github, и я объясню некоторые его основные части.

Начнем с импорта пакетов, которые мы будем использовать, и инициализации драйвера для автоматического управления браузером, с некоторыми параметрами, которые помогут не так легко обнаружить его, и будущими действиями, которые мы будем выполнять в браузере.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
from webdriver_manager.chrome import ChromeDriverManager
import random
import time

chrome_options = Options()
chrome_options.add_argument("start-maximized")
chrome_options.add_argument("--disable-blink-features=AutomationControlled")

driver_path = ChromeDriverManager().install()

driver = webdriver.Chrome(driver_path, options=chrome_options)
actions = ActionChains(driver)

Определяем константы, такие как имя пользователя и пароль для входа, и идентификаторы html-элементов, которые мы будем использовать, такие как поле ввода для имени пользователя, пароля и кнопку "Далее".

# CONSTANTS
USERNAME = "МОЙ ПОЛЬЗОВАТЕЛЬ"
PASSWORD = "МОЙ ПАРОЛЬ"
...

# HTML Elements
EMAIL_ID = "login-email"
PASSWORD_ID = "login-password"
NEXT_PAGE_CLASS = "button.primary.g-recaptcha"
....

Затем мы определяем основные функции. Это основная функция, которую мы будем использовать в основном для доступа к html-элементам, перемещения к ним, щелчка по ним и вставки определенного текста (например, нашего имени пользователя, пароля и т. д.). Она будет нашим основным браузером на странице.

def input_text(element, text_to_input)->None:
    for letter in text_to_input:
        element.send_keys(letter)
        time.sleep(random.random())

def find_element_and_input(element_id,, text_to_input, driver,  has_id = True) -> None:
    if has_id:
        element = driver.find_element(By.ID, element_id)
    else:
        element = driver.find_element(By.CLASS_NAME, element_id)
    
    actions.move_to_element(element).perform()
    element.click()
    time.sleep(1)
    if text_to_input:
        input_text(element, text_to_input)
    time.sleep(3)
    return
....

И, наконец, наша основная функция, которая фактически проверяет наличие приемов и уведомляет нас, если есть доступные приемы, в данном случае, через уведомление в консоли. Однако мы могли бы сделать так, чтобы она отправляла нам уведомление по электронной почте, отправляла сообщение через телеграмм или писала нам в Slack, чтобы привести несколько примеров.

def check_availability(AVAILABLE_CLASS, NEXT_CLASS, driver, repetitions=0):
    available = driver.find_elements(By.CLASS_NAME, AVAILABLE_CLASS)
    if len(available) > 0:
        print("Есть прием")

    elif repetitions > 4:
        next = driver.find_element(By.CLASS_NAME, NEXT_CLASS)
        next.click
        time.sleep(1)
        check_availability(driver, AVAILABLE_CLASS, NEXT_CLASS, repetitions + 1)
    else:
        print("Нет приемов")

Когда скрипт заработал, я преобразовал его в исполняемый файл, используя auto-py-to-exe, и запланировал его запуск несколько раз в день на моем ПК с помощью task scheduler, чтобы он работал автоматически.

Благодаря этому я смог получить прием намного раньше и обновить паспорт вовремя, не проведя ни одного дня с просроченными документами 🥳.

В качестве бонуса, некоторые фотографии моей поездки в Гаагу, когда я пошел делать документы.

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