Как я узнал, что моя виза не готова, сообщением в Slack
Пост актуальный для майских праздников. 6 недель назад я подал документы, чтобы получить визу в Ирландию. Вылет запланирован на 30 апреля. Существует сайт посольства, на котором публикуются списки решений по визам. Они это делают по понедельникам и четвергам. И вот я сижу в воскресенье, 28 апреля, по моей визе решения еще нет. И дальнейшие мои действия в понедельник зависят от того, будет ли мое заявление в новом отчете или нет. Если нет, то надо будет ехать в посольство и разбираться. Если есть, то дергать визовый центр. Сидеть и обновлять страничку целый день в понедельник казалось унылым времяпрепровождением, поэтому я написал скрипт на Python.
Disclaimer. Я не программист, но умею программировать. Это значит, что я не могу написать изящный и эффективный код, но я могу заставить эту шарманку делать то, что мне от нее нужно.
1. Проверка страницы на наличие нового отчета
Итак, что требуется сделать:
- Нужно спарсить эту страницу.
- Найти среди отчетов новый по новой дате (в моем случае можно искать по слову
24 April
). - Получить ссылку на этот отчет.
Код функции выглядит следующим образом:
def check_report(url, div_class, date):
embassy_page = requests.get(url)
page_text = BeautifulSoup(embassy.text, 'lxml')
tags = page_text.findAll('div', {"class": div_class})
text = ''
report_url = ''
for tag in tags:
tag_soup = BeautifulSoup(tag.text, 'lxml')
report = s(text=re.compile(date))
if len(report) > 0:
text = 'New report published'
report_url = 'https://www.dfa.ie' + tag.find('a').attrs['href']
return text, report_url
Теперь подробнее, что в этом коде происходит.
Для начала мы пользуемся библиотекой requests
, которая помогает нам скачать требуемую страницу. Затем, мы используем другую библиотеку BeautifulSoup
, которая помогает превратить эту дикую разметку страницы в более красивый и удобный вид.
До использования BeautifulSoup
:
'\r\n\r\n\r\n \r\n \r\n \t\r\n\t\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\t\r\n\r\n\r\n\r\n\r\n \r\n\tWeekly Decision Report - Department of Foreign Affairs and Trade \r\n \r\n \t \r\n\t\t\r\n \t\r\n
После:
Weekly Decision Report - Department of Foreign Affairs and Trade
С этим теперь можно как-то жить и работать. В частности в моем случае мы будем искать особый Далее идем по собранным тегам и ищем тот, внутри которого содержится дата нового отчета: Итак, что требуется сделать теперь здесь: Код функции выглядит следующим образом: При помощи опять же библиотеки Хорошо. Cкрипт нашел, допустим, мой id, но нужно же где-то меня уведомить об этом. Мы в компании у себя используем Slack в качестве мессенджера, поэтому я подумал, что мне было бы удобно получить уведомление туда. По этой ссылке можно настроить себе webhook. Там можно выбрать канал или адресата, кому запостить сообщение (возможно, для этого шага потребуется быть админом WorkSpace). Там же вы получите уникальный url для webhook, который можно использовать в коде. Пользуясь все той же библиотекой Остаток кода выглядит так: Присваиваем значения всем необходимым переменным и далее запускаем прописанные функции. Ок. Скрипт я написал, но если мне придется его самостоятельно каждый раз дергать, то я недалеко ушел от изначального состояния дел, где мне бы пришлось сидеть и обновлять страничку. В него добавил строчку: Я подумал, что мне достаточно, если этот скрипт будет отрабатываться каждые 10 минут по cron на сервере с ubuntu. В 11:50 мне пришло сообщение, что появлися новый отчет, но моей визы в нем не оказалось… После этого я поехал в посольство. Взял его штурмом (на письма и звонки не отвечали в течение нескольких недель) и в итоге получил свой паспорт с визой. В общем, скилл программирования важен в современном мире, даже если ты не программист. Он позволяет автоматизировать некоторые твои рутинные операции, что делает твой мир чуточку удобнее. На самом деле можно было бы это даже оформить в отдельный сервис, где человек просто вводит свой id и e-mail, и ему приходит сообщение о готовности визы на почту.div class
, который используется для ссылок на отчеты. Мы это видим по исходному коду страницы: 24 April
. Если такой результат найден, то вытаскиваем из него ссылку и формируем текст, что новый отчет опубликован.2. Поиск id визы в новом отчете
def check_visa(report_url, filename, visa_id, text):
pdf = requests.get(report_url)
file_path = Path(filename)
file_path.write_bytes(pdf.content)
pdfFileObj = open(filename, 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj, strict=False)
for pageNum in range(0, pdfReader.numPages):
page = str(pdfReader.getPage(pageNum).extractText().encode('utf-8')).split('\\n')
if visa_id in page:
visa_index = page.index(visa_id)
status = page[visa_index + 1]
text = text + '\t' + visa_id + '\t' + status
return text
requests
делаем запрос к этому отчету. Далее сохраняем его локально. При помощи библиотеки PyPDF2
производим чтение файла. После чего перебираем его страницы и ищем visa_id
в массиве токенов. Разметка этого pdf-файла такова, что следующим токеном после visa_id
идет непосредственно статус рассмотрения: Approved
или Refused
. Далее мы конкатенируем существующий текст с id и статусом.3. Отправка статуса сообщением в Slack
def send_to_slack(webhook_url, text):
post = {"text": "{0}".format(text)}
json_data = json.dumps(post)
req = requests.post(webhook_url, data=json_data.encode('ascii'), headers={'Content-Type': 'application/json'})
return req.status_code
requests
, делаем POST-запрос с содержимым text
по адресу webhook.4. Использование функций
url = 'https://www.dfa.ie/irish-embassy/russia/visas/weekly-decision-report/'
div_class = 'gen-content-landing__block'
date = '24 April'
filename = 'weekly_report.pdf'
visa_id = '38644112'
webhook_url = 'https://hooks.slack.com/services/...'
text, report_url = check_report(url, div_class, date)
if text != '':
text = check_visa(report_url, filename, visa_id, text)
print(send_to_slack(webhook_url, text))
5. Запуск по плану
$ crontab -e
*/10 * * * * python3 /home/ubuntu/embassy.py >/dev/null 2>&1
6. Заключение