В момент размышления над заголовком статьи ко мне пришло осознание: тема этой публикации настолько актуальна, что мне бы позавидовал любой студент. Вспоминается, как долго и мучительно я выбирал тему для диплома, когда учился на последних курсах университета, а сейчас жизненные обстоятельства сами подкидывают мне идеи. В связи с уходом ИКЕА с российского рынка 5-го июля 2022 года в магазине стартовала онлайн-распродажа. Желающих купить стильные и недорогие вещи для дома оказалось настолько много, что сайт компании в первый день распродажи перестал работать, из-за чего её перенесли на пару дней. Сотрудники компании нашли выход из сложившийся ситуации - создали электронную очередь (см. рисунок 1). Это помогло снизить нагрузку на сервера, но стрессовое бремя на пользователей сайта возросло. Потенциальным покупателям приходилось часами/днями ждать своей очереди, обновлять страницу и не отходить от компьютера. Некоторые мои знакомые потеряли 3 дня отпуска на «сизифов труд», но справедливости ради они успели сделать 4 заказа. Чтобы не тратить столько времени на сайте компании, я решил реализовать следующую идею:  «Написать за максимально короткое время программу на Python, которая через Telegram бота будет оповещать о доступности сайта интернет-магазина ИКЕА». В статье я подробно расскажу, как у меня получилось воплотить данную идею и сэкономить себе время и нервы. Первое сообщение от Telegram-бота Автоматизированное посещение сайта Заключение Обратная связь После изучения различной информации в интернете о том, как отправлять сообщения через Telegram-бота, я понял, что мне для этого необходимо получить token (ключ доступа к боту) и chat_id (уникальный идентификатор чата). Token позволит управлять ботом, например, получать сообщения, которые были ему отправлены от пользователей, или, наоборот, отправлять сообщения, получать nickname пользователей и т.д. Подробнее о том, как создать бота и получить его token, можно прочитать в спойлере. Для того, чтобы создать своего бота в Telegram, необходимо в поисковой строке мессенджера ввести следующие слово «BotFather». Перед вами появится отец всех ботов в Telegram (см. рисунок А.1).  Я предполагаю, что создаваемый нами бот наследуется от класса BotFather. После перехода в чат перед вами появится приветственное сообщение (в какой-то степени даже диктаторское): BotFather is the one bot to rule them all. Use it to create new bot accounts and manage your existing bots. ... Чтобы перейти к более детальному общению необходимо нажать кнопку «start» (в общем, как и всегда при первом общении с ботами в Telegram). Затем появится ряд опций (см. рисунок А.2). Чтобы создать своего бота, необходимо нажать/написать «newbot». Следом BotFather попросит вас дать название своему боту. Оно будет высвечивать в общем доступе (см. рисунок А.3). Я своего назвал «my_bot_ikea_is_access». Сразу оговорюсь, что нет смысла добавлять данного бота в Telegram, так как для вас он будет бесполезным. После того, как вы назовете своего бота, останется последний шаг - дать ему username (аналог логина). У username есть два ограничения: Должно оканчиваться на «bot»; Должно быть уникальным.  Если вы справились с username, получите token (см. рисунок А.4), с помощью которого в дальнейшем сможете управлять ботом.  Token получен, но этого не достаточно для отправки сообщения пользователю, потому что, во-первых, боты в Telegram не имеют права писать юзерам, которые до этого с ним не взаимодействовали (защита от спама), во-вторых, бот должен "понимать" кому именно следует отправить сообщение. Решить вторую проблему нам поможет chat_id, но, чтобы chat_id сформировался, пользователь должен самостоятельно отправить сообщение Telegram-боту. Получить chat_id поможет метод getUpdates (подробнее о методе можно почитать здесь). Сделаем GET-запрос и посмотрим на вывод. Если вы только что создали бота и с ним никто не взаимодействовал, метод вернёт пустой результат: Если с ботом было взаимодействие (например, отправлено сообщение (см. рисунок 2)), результат будет содержать системную информацию о сообщении, дату отправки сообщения, отправителя, текст сообщения и т.д.  Теперь давайте автоматизируем получение id чата. Вывод: Я понимаю, что решение по получению chat_id далеко не оптимально, поскольку может возникнуть ряд сложностей. Например, любой пользователь, обнаруживший бота, может отправить ему сообщение. В ответе, полученном с помощью метода getUpdates, будет несколько различных chat_id. Получается, что сообщение от бота, которое полагается одному пользователю, вероятнее, получит иной. В моём случае было важно написать программу за максимально короткое время, а не создавать универсальное решение На данном этапе получен token и chat_id. Можно переходить к отправке сообщения в Telegram с помощью Python. Отправить сообщение поможет метод sendMessage (подробнее о методе можно почитать здесь). Сделаем POST-запрос и посмотрим на вывод. Вывод можно посмотреть на рисунке 3. С второстепенной задачей справились, теперь можно переходить к решению основной.  В предыдущей главе была протестирована отправка сообщений в Telegram. Теперь применим эти знания для решения практической задачи. Напомню цель – необходимо купить товар в ИКЕА во время распродажи и при этом не стоять самостоятельно в электронной очереди. Сформулируем  задачу: отправлять сообщение  о доступности сайта ИКЕА в Telegram с помощью Python. В процессе было выдвинуто новое требование: Браузер и страница магазина должны быть открыты в момент отправки сообщения о доступности сайта, поскольку одна http-сессия – одно место в электронной очереди. После постановки задачи можно переходить к её решению. MVP базируется на трёх основных библиотеках: requests – позволяет отправлять http-запросы; bs4 (BeautifulSoup) – позволяет парсить HTML и XML документы; selenium – автоматизирует действия веб-браузера. Данная библиотека в основном используется для тестирования, однако в нашем случае она будет применяться для запуска браузера и интернет страницы. Для начала необходимо автоматизировать запуск браузера и интернет страницы. За это отвечает функция open_page, которая принимает в качестве параметра уникальный адрес страницы. Внутри себя эта функция вызывает две другие: add_chrome_options– отвечает за добавление новых опций. Например, можно добавить опцию options.add_argument('--headless'), тогда Chrome запустится в автономном режиме. В данном случае была добавлена одна новая опция связанная с user agent (идентифицирует браузер и операционную систему), поскольку только с ним удалось получить доступ к сайту ИКЕА (возможно, на момент прочтения статьи что-то изменится).  install_chrome_driver– отвечает за установку драйвера для управления браузером  Google Chrome.  Следующий код ChromeDriverManager().install() устанавливает наиболее актуальную версию драйвера. Конечно, устанавливать драйвер лучше вне функции open_page, так как при каждом открытии страницы он, возможно, будет устанавливаться заново. Для MVP это не критично, и высока вероятность, что при повторных открытиях страницы драйвер подтянется из кэша. После того, как будет запущен браузер и откроется интернет страница, нам нужно будет определить доступен ли сайт для заказа товаров, иными словами перешли ли мы со страницы ожидания (см. рисунок 4) на главную страницу сайта. Возникает логичный вопрос - как определить, что мы перешли на главную страницу сайта? Ответ предельно прост - сравним для этого заголовок 1-го уровня на текущей открытой странице  с <h1> заголовком главной страницы интернет-магазина (я узнал его заранее – 'ИКЕА - официальный интернет-магазин мебели ').  Если они совпадут, будем считать, что главная страница доступна. Заголовок 1-го уровня получим с помощью парсинга страницы. Функция get_ikea_html  возвращает html-код страницы, а функция get_h1 возвращает заголовок 1-го уровня (<h1>). В спойлере рассмотрим, как получить заголовок  <h1> страницы ожидания. Для примера, получим заголовок 1-го уровня страницы ожидания (см. рисунок 4) Вывод:  Осталось лишь отправить оповещение о доступности главной страницы. За отправку сообщения в Telegram отвечает процедура post_message.В качестве параметров она принимает token, chat_id (id чата - адрес получателя),  message (сообщение, которое будет отправлено получателю).  Все основные функции реализованы, теперь можем переходить к решению поставленной задачи. Код ниже запустит Chrome и откроет страницу ожидания ИКЕА, после этого он будет проверять у страницы каждую секунду заголовок 1-го уровня. Если заголовок 1-го уровня страницы совпадет с заголовком главной страницы интернет-магазина, бот отправит сообщение в телеграмм о доступности сайта.  Если возникнет необходимость отправить сообщение нескольким пользователям, можно переопределить две функции (см. в спойлере ниже) и это станет возможным. Однако в этом практически нет смысла, так как одна http-сессия - одна электронная очередь. Что это значит? Если у вас страница стала доступна, это не значит, что она доступна и у вашего знакомого.        Если хотим отправить информацию нескольким пользователем, то переопределяем функции get_chat_id и post_message следующем образом:  Прототип выше изложенного решения можно увидеть ниже на видео. В статье была описана небольшая программа на Python, которая в ходе выполнение проверяет доступность сайта интернет-магазина и в случае положительного исхода оповещает пользователя с помощью Telegram-бота. С помощью данной программы у меня получилось сэкономить себе время и заказать товары. Этот код лишь MVP. Вы можете его усовершенствовать при необходимости. Например, написать часть кода, которая будет добавлять товар в корзину или открывать сразу несколько вкладок. Программный код, используемый в статье, вы можно найти здесь. Обязательно оставляйте комментарии. Пишите в Telegram или на Почту (если mailto ссылка не сработала: ratmirmigranov@yandex.ru), с удовольствием всем отвечу. Всем спасибо, кто смог осилить статью и дошел до этого места!  ML-engineer