¿Cómo enviar una solicitud POST?


260

Encontré este script en línea:

import httplib, urllib
params = urllib.urlencode({'number': 12524, 'type': 'issue', 'action': 'show'})
headers = {"Content-type": "application/x-www-form-urlencoded",
            "Accept": "text/plain"}
conn = httplib.HTTPConnection("bugs.python.org")
conn.request("POST", "", params, headers)
response = conn.getresponse()
print response.status, response.reason
302 Found
data = response.read()
data
'Redirecting to <a href="http://bugs.python.org/issue12524">http://bugs.python.org/issue12524</a>'
conn.close()

Pero no entiendo cómo usarlo con PHP o qué es todo dentro de la variable params o cómo usarlo. ¿Puedo tener un poco de ayuda para que esto funcione?


1
La solicitud de publicación es solo una solicitud de publicación, independientemente de lo que esté en el lado del servidor.
Ondra Žižka

77
Esto envía una solicitud POST. Luego, el servidor responde con 302 (redireccionar) encabezados a su POST. ¿Qué está realmente mal?
ddinchev

1
Este script no se ve compatible con
python3.2

El equivalente a python3 de este ejemplo podría ser: pastebin.com/Rx4yfknM
jdi el

1
Lo que sugeriré es instalar el live http headercomplemento de firefox y luego abrir su url en firefox y ver la request/responseurl en el live http headercomplemento de lo que entenderá qué params and headershacer en su código.
RanRag

Respuestas:


388

Si realmente quiere manejar HTTP con Python, le recomiendo Solicitudes: HTTP para humanos . El inicio rápido POST adaptado a su pregunta es:

>>> import requests
>>> r = requests.post("http://bugs.python.org", data={'number': 12524, 'type': 'issue', 'action': 'show'})
>>> print(r.status_code, r.reason)
200 OK
>>> print(r.text[:300] + '...')

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>
Issue 12524: change httplib docs POST example - Python tracker

</title>
<link rel="shortcut i...
>>> 

No puedo obtener el mismo resultado que obtuviste anteriormente. Escribí otro número de problema en la página y luego ejecuté el script, pero no pude ver el número de problema en el resultado.
Efe Büyük

2
Cambie data = {'number': 12524, para leer data = {'number': '12524' ,. Lo hubiera cambiado yo mismo, pero las ediciones deben tener más de 6 caracteres. Gracias
kevthanewversi

2
¿Cómo obtener el resultado json?
Yohanes AI

9
Si necesita enviar un objeto JSON, debe hacerlo: en json={'number': 12524...lugar dedata=...
Seraf

3
¿Por qué la respuesta dice "Si realmente quieres manejar con HTTP usando Python"? ¿Es una mala idea manejar solicitudes HTTP? Si es así, ¿por qué? alguien puede explicar por favor?
Jan Pisl

147

Si necesita que su script sea portátil y prefiere no tener dependencias de terceros, esta es la forma en que envía la solicitud POST únicamente en Python 3.

from urllib.parse import urlencode
from urllib.request import Request, urlopen

url = 'https://httpbin.org/post' # Set destination URL here
post_fields = {'foo': 'bar'}     # Set POST fields here

request = Request(url, urlencode(post_fields).encode())
json = urlopen(request).read().decode()
print(json)

Salida de muestra:

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "foo": "bar"
  }, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Content-Length": "7", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "Python-urllib/3.3"
  }, 
  "json": null, 
  "origin": "127.0.0.1", 
  "url": "https://httpbin.org/post"
}

66
Este código solo funcionará en Python 3, como dije en la respuesta.
stil

36

No puede realizar solicitudes POST usando urllib(solo para GET), en su lugar intente usar el requestsmódulo, por ejemplo:

Ejemplo 1.0:

import requests

base_url="www.server.com"
final_url="/{0}/friendly/{1}/url".format(base_url,any_value_here)

payload = {'number': 2, 'value': 1}
response = requests.post(final_url, data=payload)

print(response.text) #TEXT/HTML
print(response.status_code, response.reason) #HTTP

Ejemplo 1.2:

>>> import requests

>>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.post("http://httpbin.org/post", data=payload)
>>> print(r.text)
{
  ...
  "form": {
    "key2": "value2",
    "key1": "value1"
  },
  ...
}

Ejemplo 1.3:

>>> import json

>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}

>>> r = requests.post(url, data=json.dumps(payload))

44
Gracias. data = json.dumps (payload) es la clave para mi caso de uso
Aram

11

Use la requestsbiblioteca para OBTENER, POSTAR, PONER o ELIMINAR presionando un punto final de la API REST. Pase el resto de la URL del punto final de la API url, la carga útil (dict) datay el encabezado / metadatos enheaders

import requests, json

url = "bugs.python.org"

payload = {"number": 12524, 
           "type": "issue", 
           "action": "show"}

header = {"Content-type": "application/x-www-form-urlencoded",
          "Accept": "text/plain"} 

response_decoded_json = requests.post(url, data=payload, headers=header)
response_json = response_decoded_json.json()

print response_json

2
Este código tiene problemas con la sangría y el nombre del parámetro del encabezado.
xilopaint

2
headersEl parámetro está mal y tampoco tenemos ningún JSON aquí. Deberíamos usarjson.dumps(pauload)
Arash Hatami

Gracias @xilopaint y ArashHatami por el error de sintaxis. Corregido ahora.
Pranzell

3

Su diccionario de datos contiene nombres de campos de entrada de formulario, simplemente mantenga sus valores correctos para encontrar resultados. El encabezado de vista de formulario configura el navegador para recuperar el tipo de datos que declara. Con la biblioteca de solicitudes es fácil enviar POST:

import requests

url = "https://bugs.python.org"
data = {'@number': 12524, '@type': 'issue', '@action': 'show'}
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept":"text/plain"}
response = requests.post(url, data=data, headers=headers)

print(response.text)

Más sobre el objeto Solicitud: https://requests.readthedocs.io/en/master/api/


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.