Ошибка "Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported" после отправки post запроса
Пробовал использовать этот код:
import requests
r = requests.post("https://job.сайт.ru/auth/self-employed/login", {"phone":"+12345678910"})
print(r.status_code)
print(r.text)
но выходит ошибка:
{"systemMessage":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported","message":"Упс! Что-то пошло не так...","errors":{}}
Как можно это исправить? Как я понял он ругается о том что кодировка UTF-8 не поддерживается, но к сожалению я не знаю как это исправить
:authority:job.сайт.ru
:method:POST
:path:/auth/self-employed/login
:scheme:https
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:ru,en;q=0.9,ko;q=0.8
это если пользоваться сайтом и сделать этот же запрос через кнопки на сайте
Ответы (1 шт):
tl;dr. Нужно передать данные через параметр json, а не просто вторым параметром:
r = requests.post(url, json={"phone":"+12345678910"})
Ошибка не в кодировке, а в ContentType в целом: application/x-www-form-urlencoded - это тип контента, который отправляется из html форм, данные при этом передаются в теле запроса, но не в виде json, а одной строкой парами ключ=значение (вида field1=value1&field2=value2, см. пример). Сервер вам отвечает, что такой тип запроса не поддерживается.
Скорее всего вам нужно передавать данные как json, а не в формате x-www-form-urlencoded.
Тип контента x-www-form-urlencoded стал из-за того, что вы передали словарь просто вторым параметром без указания имени параметра, и он попал в параметр data. Библиотека requests при получении словаря или списка кортежей в этом параметре считает, что вы пытаетесь передать данные в виде x-www-form-urlencoded. См. документацию.
Т.е. такой запрос:
r = requests.post(url, {"phone":"+12345678910"})
это то же самое что
r = requests.post(url, data={"phone":"+12345678910"})
и в итоге то же самое что
r = requests.post(url, data="phone=%2B12345678910")
Плюс превратился в %2B в результате url-кодирования (см. википедию).
Как посмотреть фактическое тело запроса:
from requests import Request
request = Request("POST", url="https://job.сайт.ru/auth/self-employed/login", data={"phone":"+12345678910"}).prepare()
print(request.body)
Вывод
phone=%2B12345678910
Чтобы преобразовать словарь в json и передать его в теле запроса, нужно использовать параметр json:
r = requests.post(url, json={"phone":"+12345678910"})
либо передать уже сконвертированный в строку (сериализованный) json в параметр data, тогда это строка будет передана в теле запроса как есть:
r = requests.post(url, data=json.dumps({"phone":"+12345678910"}))
Ну и итоговое тело запроса можно проверить:
from requests import Request
request = Request("POST", url="https://job.сайт.ru/auth/self-employed/login", json={"phone":"+12345678910"}).prepare()
print(request.body)
Вывод:
b'{"phone": "+12345678910"}'
b и одинарные кавычки просто обозначают что передаются бинарные данные, в самом теле запроса они не передаются.