Comment envoyer une demande POST?

260

J'ai trouvé ce script en ligne:

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()

Mais je ne comprends pas comment l'utiliser avec PHP ou ce que tout à l'intérieur de la variable params est ou comment l'utiliser. Puis-je s'il vous plaît avoir un peu d'aide pour essayer de faire fonctionner cela?

user1113569
la source
1
La demande de publication est simplement une demande de publication, quel que soit le côté serveur.
Ondra Žižka
7
Cela envoie une demande POST. Ensuite, le serveur répond avec 302 en-têtes (redirection) à votre POST. Qu'est-ce qui ne va pas?
ddinchev
1
Ce script ne semble pas compatible avec python3.2
jdi
L'équivalent python3 de cet exemple pourrait être: pastebin.com/Rx4yfknM
jdi
1
Ce que je vais suggérer est d'installer l' live http headeraddon de Firefox et d'ouvrir votre URL dans Firefox et de voir l' request/responseURL dans l' live http headeraddon que vous comprendrez ce que params and headersfait votre code.
RanRag

Réponses:

388

Si vous voulez vraiment gérer avec HTTP en utilisant Python, je recommande fortement Requests: HTTP for Humans . Le quickstart POST adapté à votre question est:

>>> 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...
>>> 
parkerfath
la source
Je ne peux pas obtenir le même résultat que vous l'avez fait ci-dessus. J'ai écrit un autre numéro de problème sur la page, puis j'ai exécuté le script, mais je n'ai pas pu voir le numéro de problème sur le résultat.
Efe Büyük
2
Veuillez modifier data = {'number': 12524, pour lire data = {'number': '12524' ,. Je l'aurais changé moi-même mais les modifications doivent comporter plus de 6 caractères. Merci
kevthanewversi
2
Comment obtenir le résultat JSON?
Yohanes AI
9
Si vous devez envoyer un objet JSON, vous devez faire: json={'number': 12524...au lieu dedata=...
Seraf
3
pourquoi la réponse dit "Si vous voulez vraiment gérer avec HTTP en utilisant Python"? est-ce une mauvaise idée de gérer les requêtes HTTP? si oui, pourquoi? quelqu'un peut-il expliquer s'il vous plaît?
Jan Pisl
147

Si vous avez besoin que votre script soit portable et que vous préférez ne pas avoir de dépendances tierces, voici comment envoyer une requête POST uniquement 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)

Exemple de sortie:

{
  "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"
}
toujours
la source
6
Ce code ne fonctionnera qu'en Python 3, comme je l'ai dit dans la réponse.
jusqu'au
36

Vous ne pouvez pas réaliser de requêtes POST en utilisant urllib(uniquement pour GET), essayez plutôt d'utiliser le requestsmodule, par exemple:

Exemple 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

Exemple 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"
  },
  ...
}

Exemple 1.3:

>>> import json

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

>>> r = requests.post(url, data=json.dumps(payload))
d1jhoni1b
la source
4
Merci. data = json.dumps (payload) est la clé de mon utilisation
Aram
11

Utilisez la requestsbibliothèque pour GET, POST, PUT ou DELETE en frappant un point de terminaison REST API. Passez l'url du point de terminaison api restante url, la charge utile (dict) dataet l' en -tête / métadonnées dansheaders

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
Pranzell
la source
2
Ce code a des problèmes avec l'indentation et le nom du paramètre d'en-tête.
xilopaint
2
headersle paramètre est incorrect et nous n'avons pas non plus de json ici. Nous devrions utiliserjson.dumps(pauload)
Arash Hatami
Merci @xilopaint et ArashHatami pour l'erreur de syntaxe. Corrigé maintenant.
Pranzell
3

Votre dictionnaire de données contient des noms de champs de saisie de formulaire, il vous suffit de conserver à droite leurs valeurs pour trouver des résultats. vue formulaire En-tête configure le navigateur pour récupérer le type de données que vous déclarez. Avec la bibliothèque de requêtes, il est facile d'envoyer 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)

En savoir plus sur l'objet de demande: https://requests.readthedocs.io/en/master/api/

Anastasia Didan
la source
1

Si vous ne souhaitez pas utiliser un module que vous devez installer comme requests, et que votre cas d'utilisation est très basique, vous pouvez utiliserurllib2

urllib2.urlopen(url, body)

Voir la documentation urllib2ici: https://docs.python.org/2/library/urllib2.html .

Phil
la source