Использование csrf-токена при запросах к сайту через Python requests
В ответ на запрос на сайт выводится сообщение "Ошибка проверки CSRF токена. Необходимо обновить страницу". Токен формируется при заходе на сайт (отправляю GET-запрос) и находится в коде страницы в элементе с id "sessid". Однако, при отправке POST-запроса, передавая при этом и найденный токен, вместо ожидаемых данных получаю сообщение о том, что токен ошибочный.
Для решения проблемы пробовал разные способы, которые предлагаются в сети:
- установка в запросах библиотеки requests параметров
verify = Falseи/илиallow_redirects = True - использование одной сессии для запросов и установка в headers соответствующих значений referer и cookie
К сожалению, ничего из этого не помогло. Есть ли мысли в чём здесь дело и как решить проблему?
Пример кода, который получает и печатает токен, отправляет запрос и выводит ответ:
import requests
from bs4 import BeautifulSoup
# url для получения токена
token_url = "https://boxberry.ru/calculate_the_cost_of_sending/"
# открытие сессии и get-запрос для получения токена
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"}
s = requests.Session()
token_resp = s.get(url = token_url, headers = headers)
# парсинг токена из кода полученной страницы
soup = BeautifulSoup(token_resp.text, "lxml")
token = str(soup.find(id = "sessid")["value"])
print("CSRF-token: {}".format(token))
# url для для запроса (стоимости перевозки) с использованием токена
price_url = "https://boxberry.ru/local/components/bberry/calculator.express/component.php"
# входные данные для запроса (стоимости перевозки) с использованием токена
price_input_data = {"data": {"ArrayOfServices": {"ServiceCalcID":[]},
"sender_city_id": "68",
"recipient_city_id": "90",
"depth": "1",
"width": "1",
"height": "1",
"Weight": 5000,
"Ordersum": 100,
"IdClient": "",
"promoCode": "",
"Deliverysum": "",
"Paysum": 0,
"acquiring": 0,
"sessid": token},
"ajax": "DeliveryCostArray"}
# формируем headers
headers={"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Referer": token_url,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"}
headers.update({"Cookie": "; ".join([x.name + "=" + x.value for x in s.cookies])})
# post-запрос (стоимости перевозки)
price_resp = s.post(url = price_url, data = price_input_data, headers = headers)
print("Response text: {}".format(price_resp .text))
Полученный результат:
CSRF-token: 73d68a96bf9845ca65dc057318a68785
Response text: Ошибка проверки CSRF токена. Необходимо обновить страницу.
А должно быть что-то вроде этого:
CSRF-token: 73d68a96bf9845ca65dc057318a68785
Response text: [{"deliveryType_id":3,"price":"507.005","DeliveryPeriod":14,"priceBase":"507","ArrayOfServices":{"Service":[{"Name":"Доплата за плотность","description":"","price":"0"},{"Name":"Страховой сбор","description":"","price":"0.005"}]}}]