
Кнопка на веб-странице почти всегда запускает сетевой запрос: браузер отправляет HTTP-сообщение с методом, заголовками, cookies и телом формы. Библиотека Python requests позволяет воспроизвести этот обмен без участия браузера, если точно повторить структуру запроса. Для этого используются данные из вкладки Network в инструментах разработчика: URL, метод (GET или POST), параметры формы и заголовки вроде Content-Type и Referer.
Практическая задача сводится к трём шагам: перехватить запрос, который формируется при клике по кнопке, извлечь из него все обязательные поля и отправить тот же набор данных через requests.Session(). Сессия сохраняет cookies и идентификаторы, которые сервер выдал при первом открытии страницы, поэтому повторный запрос выглядит для сервера как действие живого пользователя.
Чаще всего кнопки работают через POST-формы или AJAX-вызовы. В обоих случаях сервер проверяет скрытые поля, например CSRF-токены, и их отсутствие приводит к ответам 403 или 400. Поэтому при разборе запроса важно скопировать не только видимые параметры, но и все служебные значения, передаваемые в теле или заголовках.
Использование requests даёт контроль над каждым байтом отправляемых данных: можно вручную задать кодировку, порядок параметров и заголовки браузера. Это позволяет нажимать кнопки, запускать действия в личных кабинетах и отправлять формы напрямую из Python-скрипта без эмуляции DOM или запуска WebDriver.
Как определить HTTP-метод и URL, которые вызывает кнопка в браузере

Открой инструменты разработчика в браузере (F12) и перейди во вкладку Network. Очисти список запросов, затем нажми кнопку на странице. В журнале появится один или несколько новых запросов, которые и соответствуют действию кнопки.
- Отсортируй записи по времени, чтобы нужный запрос был вверху списка.
- Обрати внимание на колонку Method: там будет указано GET, POST, PUT или другой HTTP-метод.
- В колонке Name или URL будет показан путь, по которому ушёл запрос.
Кликни по найденному запросу и открой вкладку Headers. В блоке General отображаются ключевые данные: точный URL и метод, которые необходимо повторить в Python.
- Request URL – адрес, который нужно передать в
requests.get()илиrequests.post(). - Request Method – тип запроса, от которого зависит способ отправки данных.
Если кнопка работает через JavaScript и отправляет AJAX-запрос, его можно узнать по заголовку X-Requested-With: XMLHttpRequest. Такие запросы часто идут на отдельные API-эндпоинты, отличающиеся от адреса самой страницы.
Для форм с отправкой через кнопку проверь вкладку Payload или Form Data. Если данные присутствуют, используется POST, и URL из Request URL является точкой приёма формы. При отсутствии тела запроса и наличии параметров в адресной строке применяется GET.
- Найти запрос в Network после клика.
- Скопировать Request URL.
- Зафиксировать Request Method.
- Проверить, есть ли тело запроса или параметры в URL.
Эти два значения полностью определяют, какую функцию из библиотеки requests нужно вызвать и по какому адресу, чтобы имитировать нажатие кнопки.
Какие заголовки и cookies нужно передать, чтобы сервер принял запрос

После определения URL и метода открой тот же запрос во вкладке Headers и скопируй набор заголовков, которые браузер отправляет при клике по кнопке. Минимальный комплект почти всегда включает Host, User-Agent, Accept, Accept-Language, Referer и Content-Type. Отсутствие Referer или несовпадение User-Agent нередко приводит к отклонению запроса защитными фильтрами.
Особое внимание уделяй Content-Type: для HTML-форм он обычно равен application/x-www-form-urlencoded, для отправки JSON – application/json, для загрузки файлов – multipart/form-data. Это значение должно совпадать с форматом тела, которое передаётся через requests.post().
В блоке Request Headers скопируй также служебные поля, используемые антибот-системами, например X-Requested-With, Origin и Sec-Fetch-Site. Они позволяют серверу проверить, что запрос пришёл с ожидаемого домена и из браузерного контекста.
Cookies находятся во вкладке Cookies или в заголовке Cookie. В них обычно содержатся идентификаторы сессии, например PHPSESSID, sessionid или токены авторизации. Без этих значений сервер воспринимает запрос как анонимный и может вернуть редирект на страницу входа или код 403.
В Python передавай cookies через объект requests.Session(), а не вручную в каждом вызове. Сессия автоматически подставляет их в заголовок Cookie при отправке запроса кнопки и сохраняет новые значения, которые сервер возвращает в ответах.
Заголовки передаются в виде словаря параметром headers. Они должны точно повторять браузерные значения, включая регистр и формат. Даже лишний пробел или другая кодировка могут привести к тому, что сервер не свяжет запрос с активной сессией.
Как получить и отправить скрытые поля формы при клике кнопки

Скрытые поля находятся в HTML-разметке формы и передаются серверу вместе с нажатием кнопки. В инструментах разработчика открой вкладку Elements, найди тег <form> и просмотри все элементы <input type=»hidden»>. Их атрибуты name и value формируют часть тела POST-запроса.
- CSRF-токены обычно имеют имена вроде csrf_token, _token или authenticity_token.
- Идентификаторы объектов передаются как скрытые поля с числовыми значениями.
- Флаги состояния формы кодируются строками true, 1 или короткими хэшами.
Альтернативный способ – посмотреть вкладку Payload в Network для запроса кнопки. В разделе Form Data будут показаны все поля, включая скрытые, в том виде, в котором они отправлены браузером.
- Скопировать пары ключ–значение из Form Data.
- Добавить их в словарь Python для параметра data в
requests.post(). - Проверить, что кодировка соответствует Content-Type.
Если страница обновляет скрытые поля динамически через JavaScript, сначала нужно выполнить GET-запрос страницы и извлечь значения из полученного HTML. Для этого используется парсер вроде BeautifulSoup, который находит нужные input по имени.
Отправка формы без актуальных скрытых полей почти всегда приводит к ошибке валидации, поэтому эти значения должны обновляться перед каждым нажатием кнопки, если сервер генерирует их заново при загрузке страницы.
Как собрать тело POST-запроса для имитации нажатия кнопки

Тело POST-запроса формируется из всех полей, которые браузер отправляет при клике кнопки. В Network открой запрос и в разделе Payload скопируй список Form Data или JSON-объект, если используется API. Эти данные должны быть переданы в Python без изменений в именах параметров и их значениях.
Для форм с типом application/x-www-form-urlencoded тело представляет собой набор пар ключ–значение, который в requests передаётся через параметр data. Порядок ключей может иметь значение на серверах с жёсткой проверкой подписи запроса, поэтому его лучше сохранять таким же, как в браузере.
Если кнопка отправляет JSON, в заголовке Content-Type будет указано application/json, а тело нужно передавать через параметр json. При этом строки, числа и логические значения должны совпадать с теми, что видны во вкладке Payload, без автоматических преобразований типов.
Для запросов с файлами или бинарными данными используется multipart/form-data. В этом случае каждая часть тела содержит имя поля и его содержимое, а границы формируются библиотекой requests, если данные передаются через параметр files и data одновременно.
Кнопка часто добавляет собственный параметр, например имя и значение элемента <button> или <input type=»submit»>. Этот параметр присутствует в Form Data и его отсутствие приводит к тому, что сервер не распознаёт действие, поэтому он должен быть включён в тело POST-запроса.
Как обработать редиректы и статус-коды после отправки запроса

После отправки POST-запроса, имитирующего нажатие кнопки, сервер почти всегда возвращает код состояния, по которому определяется результат операции. Объект ответа requests содержит поле status_code и историю редиректов в response.history, что позволяет понять, был ли переход на другую страницу или возникла ошибка.
Редиректы с кодами 301, 302, 303 и 307 используются для перенаправления пользователя, например на страницу подтверждения или входа. По умолчанию requests следует им автоматически, поэтому конечный ответ может иметь код 200, даже если кнопка сначала вернула 302.
| Код | Значение при клике кнопки | Действие в Python |
|---|---|---|
| 200 | Действие выполнено, сервер вернул страницу или данные | Проверить тело ответа и убедиться, что операция прошла |
| 302 | Перенаправление, часто после успешной отправки формы | Посмотреть response.history и финальный URL |
| 401 | Отсутствует авторизация | Обновить cookies или выполнить вход |
| 403 | Запрос отклонён фильтрами | Проверить заголовки и CSRF-токен |
| 500 | Ошибка на стороне сервера | Повторить запрос или изменить данные |
Если требуется анализировать каждый шаг перенаправления, параметр allow_redirects=False отключает автоматический переход. Это позволяет получить исходный код 302 или 303 и вручную выполнить следующий запрос по адресу из заголовка Location.
Финальный URL после всех редиректов доступен в response.url. Его сравнение с ожидаемой страницей позволяет определить, распознал ли сервер действие кнопки или отправил пользователя на форму повторного ввода данных.
Как проверить результат нажатия кнопки по ответу сервера
Результат клика определяется не фактом получения кода 200, а содержимым ответа. В объекте requests.Response доступны поля text, content и json(), которые показывают, что именно вернул сервер после обработки нажатия кнопки.
Для HTML-страниц нужно искать маркеры успешного действия: изменение заголовка, появление сообщения, исчезновение формы или переход на другой путь в response.url. Совпадение этих признаков с тем, что отображает браузер, означает, что кнопка была обработана корректно.
Если сервер отвечает JSON, в теле обычно присутствуют поля статуса, например success, status или error. Их значения позволяют программно определить, была ли операция принята, отклонена или требует дополнительных данных.
Некоторые сайты возвращают одинаковую страницу при ошибке и при успехе, меняя только скрытые элементы или текст уведомления. В таких случаях сравнение хэша или длины response.text с эталонным ответом из браузера помогает выявить различия.
Дополнительный способ проверки – выполнить повторный GET-запрос к ресурсу, который должен измениться после клика кнопки, и убедиться, что данные обновились, например запись появилась в списке или статус объекта сменился.
Как автоматизировать повторные нажатия с сохранением сессии

Для серии кликов по одной и той же кнопке необходимо использовать requests.Session(), так как именно объект сессии хранит cookies, заголовки и параметры соединения между запросами. Без него каждый POST будет восприниматься сервером как новое посещение.
Первый запрос обычно представляет собой GET страницы с кнопкой, который инициализирует сессию и выдаёт cookies и CSRF-токены. Эти данные автоматически сохраняются в объекте Session и подставляются в последующие POST-запросы без ручного копирования.
При каждом повторном нажатии кнопки сервер может выдавать новые скрытые поля или обновлённые токены. Поэтому цикл автоматизации должен включать повторный GET страницы перед очередным POST, чтобы извлечь актуальные значения и не получить отказ по причине устаревших параметров.
Сама отправка выполняется через один и тот же объект сессии, что позволяет серверу связать все клики с одним пользователем. Это важно для лимитов, корзин, очередей или любых сценариев, где состояние хранится на стороне сервера.
После каждого POST проверяй код ответа и содержимое, чтобы определить, был ли клик принят. При появлении редиректа на страницу входа или ошибки 403 сессию нужно переинициализировать и повторить цепочку запросов.
Вопрос-ответ:
Почему сервер принимает клик кнопки в браузере, но отклоняет такой же запрос из Python requests?
Чаще всего не совпадают заголовки и cookies. Браузер отправляет Referer, Origin, User-Agent и набор session cookies, по которым сервер связывает действие с открытой страницей и конкретным пользователем. Если в requests передать только URL и data, сервер видит анонимный запрос и возвращает 401 или 403. Нужно копировать заголовки из Network и использовать requests.Session, чтобы cookies, полученные при загрузке страницы, автоматически прикладывались к POST-запросу кнопки.
Как понять, какой именно параметр в теле POST указывает на нажатую кнопку?
Во вкладке Payload в Network видно, что вместе с полями формы отправляется имя и значение элемента <button> или <input type=»submit»>. Например, это может быть confirm=1 или action=save. При клике другой кнопки значение меняется. Этот параметр нужно включать в data при отправке через requests, иначе сервер не сможет определить, какое действие запрошено.
Что делать, если CSRF-токен меняется после каждого клика и следующий запрос перестаёт работать?
Нужно перед каждым POST выполнять GET страницы с формой через тот же объект Session и извлекать свежий токен из HTML. После этого он подставляется в data нового запроса. Такой цикл отражает поведение браузера, который при перезагрузке страницы получает обновлённые скрытые поля и передаёт их при следующем нажатии кнопки.
Как проверить, что кнопка реально сработала, если сервер возвращает одну и ту же страницу?
Нужно сравнить тело ответа или выполнить дополнительный GET к ресурсу, который должен измениться. Например, после добавления записи кнопкой можно запросить список и убедиться, что там появился новый элемент. Также помогает анализ response.url и response.history: переход на другой путь или появление параметров часто указывает, что сервер принял действие.
