Отладка по HTTP статусу

По HTTP статусам клиент узнаёт результат своего запроса к серверу. В качестве клиента часто выступает браузер, в качестве сервера — сайт. Если браузер делает запрос к странице, которая была перенесена на другой URL, сайт возвращает ему ответ со статусом 302. Так браузер понимает, что страница была перенесена на другой адрес. Он автоматически переходит по новому адресу, который ему сообщил сервер в том же ответе.

Клиент — это не всегда браузер. Если вы делаете запрос к API ВКонтакте, вы тоже клиент. И в ответе от сайта вам тоже вернётся статус. Стоит разбираться в статусах ответов, чтобы понимать, что сервер хотел вам сказать.

Статус ответа всегда состоит из трёх цифр. Первая цифра указывает тип ответа:

  • 1 — информационный. Он редко встречается. Например, 101, «Switching Protocols». Если отправить запрос по адресу http://some_site.com, а сайт хочет общаться по HTTPS, он попросит вас переключиться с помощью этого статуса.
  • 2 — успешный. Ответ 200 так и называется: «OK».
  • 3 — перенаправление. Если сайт переехал на новый адрес, вы получите 301 —«Moved Permanently».
  • 4 — ошибка клиента. Если клиент попросил страницу, которой на сайте нет, он получит 404 — «Not Found». С сайтом всё в порядке, ошибка в запросе.
  • 5 — ошибка сервера. Если сайт не работает, вы получите 500 — «Internal Server Error». Разработчики сайта что-то поломали, клиент не виноват.

Диагностика ошибок

Для начала узнайте статус ответа:

Если пользуетесь requests:

response = requests.get('https://dvmn.org')
print(response.status_code)  # выведет в консоль 200

Если используете urllib:

response = urllib.urlopen('https://dvmn.org')
print(response.getcode())  # выведет в консоль 200

Но если статус 200, это не значит, что ошибки нет. Это зависит от добросовестности разработчиков. API ВКонтакте всегда присылает 200, а ошибки прячет в текст ответа.

Посмотреть ответ через requests:

response = requests.get('https://api.vk.com/method/wall.post')
print("status:", response.status_code)
print("text:", response.text)

Посмотреть через urllib:

response = urllib.urlopen('https://api.vk.com/method/wall.post')
print("status:", response.getcode())
print("text:", response.read())

В обоих случаях выведется:

status: 200
text: {
    "error": {
    "error_code": 15,
    "error_msg": "Access denied: user should be group editor",
    ...
}

401 Unauthorized, не авторизован

Сервер хочет убедиться, что вы тот, за кого себя выдаёте. Ему нужен ваш логин/пароль или специальный ключ — «токен». Без этого он откажется с вами работать.

Процесс передачи логина/пароля или токена и называют "Авторизация".

Как исправить

Приложите к запросу токен или логин/пароль. Действуйте так, как указано в документации к API. Как передать токен.

403 Forbidden, доступ запрещён

Сервер решил, что у вас нет доступа к методу, который вы вызвали.

401 и 403 похожи, ведь если вы не не авторизованы, то и доступ вам запрещён. Но всё же у 403 бывает и другое значение: возможно, вы авторизованы, но у вас нет прав. Если вы хотите получить переписки другого пользователя, вы получите 403.

Как исправить

Возможно, вы не авторизовались, а метод требует авторизации. Как это сделать ищите документации к API, которым пользуетесь. Как передать токен.

Вы могли авторизоваться, но неправильно. То есть отправили токен, но сервер не нашёл его в запросе, потому что искал в другом месте. Сверьтесь с документацией к API, которым пользуетесь. Убедитесь, что отправляете токен в аргументе/заголовке с правильным названием.

Возможно, вы отправили запрос не на тот адрес или пытаетесь сделать что-то, на что у вас нет прав. Перепроверьте аргументы, которые отправляете в запросе.

404 Not Found, не найден

Вы пытаетесь обратиться по адресу, на котором ничего нет.

Как исправить

Скорее всего, вы опечатались в адресе. Проверьте в документации адрес метода к которому шлёте запрос.

Возможно, дело снова в авторизации. Иногда сервер отвечает 404, чтобы скрыть, что такая страница вообще существует. Как авторизоваться ищите в документации API, которым пользуетесь.

405 Method Not Allowed, метод не поддерживается

Сервер получил запрос с методом, который не ожидал.

Как исправить

Лучший способ — найти в документации, какой метод использовать.

Если не получилось, попробуйте угадать. Чаще всего используют GET и POST.

406 Not Acceptable, неприемлемо

Сервер не знает как ему перевести данные из одного формата данных в другой.

Как исправить

Часто такое случается, когда сервис ожидает запрос в формате JSON, а ему отправили строку. В документации API обычно пишут какой тип данных ожидается в запросе. Сверьтесь с ней. Как отправть JSON, а не строку.