2014-09-19 2 views
0

Возможно ли использование urllib или urllib2 для отправки данных с запросом POST? Звучит странно, но API, который я использую, отправляет пустые данные в запросе POST.Как отправить запрос POST без данных

Я пробовал следующее, но, похоже, выдает запрос GET из-за отсутствия данных POST.

url = 'https://site.com/registerclaim?cid=' + int(cid) 
values = {} 
headers = { 
    'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36', 
    'X-CRFS-Token' : csrfToken, 
    'X-Requested-With' : 'XMLHttpRequest' 
} 

data = urllib.urlencode(values) 
req  = urllib2.Request(url, data, headers) 
resp = opener.open(req) 

Я получаю 404 исключение, которое является то, что API возвращает при попытке доступа к странице с помощью «GET» запрос. Я проверил все переменные, чтобы убедиться, что они установлены правильно, и они есть.

Рекомендации?

+0

Согласно [docs] (https://docs.python.org/3.0/library/urllib.request.html), urllib не предоставляет явный способ установки типа запроса. В нескольких местах он указывает, что тип запроса задается наличием или отсутствием данных: «Если URL использует идентификатор схемы http, необязательный аргумент данных может быть задан для указания запроса POST (обычно тип запроса GET) ._ " –

+0

Что-то еще не так. Когда 'data' является пустой строкой, отправляется пустой орган POST. –

+0

Я попробую с пустой строкой. –

ответ

1

Ваш диагноз неверный; urllib2будет отправить пустое тело POST в вашем случае:

>>> import urllib, urllib2 
>>> url = 'http://httpbin.org/post?cid=42' 
>>> headers = { 
...  'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36', 
...  'X-CRFS-Token': 'csrf_token_mocked', 
...  'X-Requested-With' : 'XMLHttpRequest' 
... } 
>>> values = {} 
>>> data = urllib.urlencode(values) 
>>> req  = urllib2.Request(url, data, headers) 
>>> req.has_data() 
True 
>>> req.get_method() 
'POST' 
>>> resp = urllib2.urlopen(req) 
>>> body = resp.read() 
>>> print body 
{"args": {"cid": "42"}, "data": "", "files": {}, "form": {}, "headers": {"Accept-Encoding": "identity", "Connection": "close", "Content-Length": "0", "Content-Type": "application/x-www-form-urlencoded", "Host": "httpbin.org", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36", "X-Crfs-Token": "csrf_token_mocked", "X-Request-Id": "a14f84f5-a355-4b8a-8b34-cb42808b8b09", "X-Requested-With": "XMLHttpRequest"}, "json": null, "origin": "81.134.152.4", "url": "http://httpbin.org/post?cid=42"} 
>>> from pprint import pprint 
>>> import json 
>>> pprint(json.loads(body)) 
{u'args': {u'cid': u'42'}, 
u'data': u'', 
u'files': {}, 
u'form': {}, 
u'headers': {u'Accept-Encoding': u'identity', 
       u'Connection': u'close', 
       u'Content-Length': u'0', 
       u'Content-Type': u'application/x-www-form-urlencoded', 
       u'Host': u'httpbin.org', 
       u'User-Agent': u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36', 
       u'X-Crfs-Token': u'csrf_token_mocked', 
       u'X-Request-Id': u'a14f84f5-a355-4b8a-8b34-cb42808b8b09', 
       u'X-Requested-With': u'XMLHttpRequest'}, 
u'json': None, 
u'origin': u'81.134.152.4', 
u'url': u'http://httpbin.org/post?cid=42'} 

Некоторые вещи, чтобы отметить:

  • http://httpbin.org/post маршрут принимает только методы POST; в противном случае он вернет ответ 405.
  • Метод req.get_method() используется для определения способа использования при отправке запроса; вы можете увидеть, что он будет использовать POST, хотя values пуст. req.get_method() определяет метод, используемый на основе ответа req.has_data(), и , что метод возвращает True, если атрибутом data не является None. Пустая строка квалифицируется здесь как имеющая данные.
  • Ответ http://httpbin.org/post показывает заголовки запроса; заголовок длины содержимого был установлен в 0, указывая пустой корпус POST.

Итак, вопрос в следующем: насколько вы уверены, что у вас есть все необходимое для успешного завершения POST? Возможно, требуется заголовок Referer, или, возможно, вы неправильно поняли, какие параметры переданы, а тело POST - , а не должно быть пустым.

+0

Я протестировал 'req.get_method()' и отправил его как «POST». Так что проблема в другом месте. Очень странно. Я отвечу на ваш ответ, хотя из-за того, что я не мог найти что-либо в Google о отправке пустых запросов «POST», а кто-то другой может найти это полезным. –

+0

Проблема была в том, что я неправильно назвал «X-CRFS-токен». Мне потребовалось несколько часов, чтобы найти это. Удивленный, пользователь SO не заметил его. Еще раз спасибо, приятель. –

+1

@JamesJeffery: Хех, и я даже не заметил, что я произнес это иначе, чем вы, по издеваемому значению. Я написал этот аббревиат слишком много раз. –

Смежные вопросы