Hacer una llamada POST en lugar de usar urllib2


Hay un montón de cosas por ahí en urllib2 y POST llamadas, pero estoy atascado en un problema.

Estoy tratando de hacer una simple llamada POST a un servicio:

url = 'http://myserver/post_service'
data = urllib.urlencode({'name' : 'joe',
                         'age'  : '10'})
content = urllib2.urlopen(url=url, data=data).read()
print content

Puedo ver los registros del servidor y dice que estoy haciendo llamadas GET, cuando estoy enviando los datos argumento a urlopen.

La biblioteca está generando un error 404 (no encontrado), que es correcto para una llamada GET, las llamadas POST se procesan bien (también estoy tratando con un POST dentro de un formulario HTML).

Author: Cœur, 2011-06-14

7 answers

Esto puede haber sido contestado antes: Python URLLib / URLLib2 POST.

Es probable que su servidor esté realizando una redirección 302 de http://myserver/post_service a http://myserver/post_service/. Cuando se realiza la redirección 302, la solicitud cambia de POST a GET (ver Problema 1401). Intente cambiar url a http://myserver/post_service/.

 45
Author: Gregg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:59

Hazlo por etapas, y modifica el objeto, así:

# make a string with the request type in it:
method = "POST"
# create a handler. you can specify different handlers here (file uploads etc)
# but we go for the default
handler = urllib2.HTTPHandler()
# create an openerdirector instance
opener = urllib2.build_opener(handler)
# build a request
data = urllib.urlencode(dictionary_of_POST_fields_or_None)
request = urllib2.Request(url, data=data)
# add any other information you want
request.add_header("Content-Type",'application/json')
# overload the get method function with a small anonymous function...
request.get_method = lambda: method
# try it; don't forget to catch the result
try:
    connection = opener.open(request)
except urllib2.HTTPError,e:
    connection = e

# check. Substitute with appropriate HTTP code.
if connection.code == 200:
    data = connection.read()
else:
    # handle the error case. connection.read() will still contain data
    # if any was returned, but it probably won't be of any use

De esta manera le permite extender a hacer PUT, DELETE, HEAD y OPTIONS también solicita, simplemente sustituyendo el valor de method o incluso envolviéndolo en una función. Dependiendo de lo que esté tratando de hacer, también puede necesitar un controlador HTTP diferente, por ejemplo, para la carga de archivos múltiples.

 40
Author: Bemmu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-25 19:25:50

El módulo requests puede aliviar su dolor.

url = 'http://myserver/post_service'
data = dict(name='joe', age='10')

r = requests.post(url, data=data, allow_redirects=True)
print r.content
 13
Author: Michael Kent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-29 16:40:30

Tener una lectura del urllib Falta Manual. Se extrae de allí el siguiente ejemplo simple de una solicitud POST.

url = 'http://myserver/post_service'
data = urllib.urlencode({'name' : 'joe', 'age'  : '10'})
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
print response.read()

Como sugiere @Michael Kent considere solicitudes, es genial.

EDIT: Dicho esto, no sé por qué pasar datos a urlopen() no resulta en una solicitud POST; debería. Sospecho que su servidor está redirigiendo, o se está portando mal.

 7
Author: Rob Cowie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-14 19:18:10

debería enviar un MENSAJE si proporciona un parámetro de datos (como lo está haciendo):

De los documentos: "la solicitud HTTP será un POST en lugar de un GET cuando se proporcione el parámetro data"

So.. agregue algunos resultados de depuración para ver qué pasa desde el lado del cliente.

Puede modificar su código a esto e intentarlo de nuevo:

import urllib
import urllib2

url = 'http://myserver/post_service'
opener = urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1))
data = urllib.urlencode({'name' : 'joe',
                         'age'  : '10'})
content = opener.open(url, data=data).read()
 4
Author: Corey Goldberg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-14 19:17:27

Prueba esto en su lugar:

url = 'http://myserver/post_service'
data = urllib.urlencode({'name' : 'joe',
                         'age'  : '10'})
req = urllib2.Request(url=url,data=data)
content = urllib2.urlopen(req).read()
print content
 1
Author: rupello,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-14 19:12:30
url="https://myserver/post_service"
data["name"] = "joe"
data["age"] = "20"
data_encoded = urllib2.urlencode(data)
print urllib2.urlopen(url + "?" + data_encoded).read()

Puede ser que esto pueda ayudar

 -3
Author: Vijay Chander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-16 04:25:05