Come inviare una richiesta POST?


260

Ho trovato questo script online:

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

Ma non capisco come usarlo con PHP o cosa sia tutto all'interno della variabile params o come usarlo. Posso per favore avere un piccolo aiuto nel tentativo di farlo funzionare?


1
La richiesta di post è solo una richiesta di post, indipendentemente dal lato server.
Ondra Žižka,

7
Questo invia una richiesta POST. Quindi il server risponde con 302 (reindirizzamento) delle intestazioni al POST. Cosa c'è di veramente sbagliato?
ddinchev,

1
Questo script non sembra compatibile con
python3.2

L'equivalente di python3 di questo esempio potrebbe essere: pastebin.com/Rx4yfknM
jdi

1
Quello che suggerirò è installare l' live http headeraddon di Firefox e quindi aprire l'URL in Firefox e vedere l' request/responseURL live http headernell'addon di quanto capirai cosa params and headersfai nel tuo codice.
RanRag

Risposte:


388

Se vuoi davvero gestire HTTP con Python, consiglio vivamente Richieste: HTTP per gli umani . La guida introduttiva POST adattata alla tua domanda è:

>>> 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...
>>> 

Non riesco ad ottenere lo stesso risultato come hai fatto sopra. Ho scritto un altro numero di problema sulla pagina e quindi ho eseguito lo script ma non sono riuscito a vedere il numero di problema sul risultato.
Efe Büyük,

2
Modifica i dati = {'numero': 12524, per leggere i dati = {'numero': '12524' ,. L'avrei cambiato da solo, ma le modifiche devono contenere più di 6 caratteri. Grazie
kevthanewversi il

2
Come ottenere il risultato JSON?
Yohanes AI,

9
Se devi inviare un oggetto JSON dovresti fare: json={'number': 12524...invece didata=...
Seraf

3
perché la risposta dice "Se vuoi davvero gestire l'HTTP usando Python"? è una cattiva idea gestire le richieste HTTP? se è così, perché? qualcuno può spiegare per favore?
Jan Pisl,

147

Se hai bisogno che il tuo script sia portatile e preferisci non avere dipendenze di terze parti, ecco come inviare la richiesta POST esclusivamente in 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)

Uscita campione:

{
  "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"
}

6
Questo codice funzionerà solo in Python 3, come ho detto nella risposta.
stil

36

Non puoi ottenere richieste POST utilizzando urllib(solo per GET), invece prova a utilizzare il requestsmodulo, ad esempio:

Esempio 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

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

Esempio 1.3:

>>> import json

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

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

4
Grazie. data = json.dumps (payload) è la chiave del mio caso d'uso
Aram

11

Utilizzare la requestslibreria per GET, POST, PUT o DELETE colpendo un endpoint API REST. Passa l'URL dell'endpoint API rimanente in url, payload (dict) in datae header / metadata inheaders

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
Questo codice presenta problemi con rientro e nome param dell'intestazione.
xilopaint,

2
headersil parametro è sbagliato e anche qui non abbiamo json. Dovremmo usarejson.dumps(pauload)
Arash Hatami il

Grazie a @xilopaint e ArashHatami per l'errore di sintassi. Corretto ora.
Pranzell,

3

Il tuo dizionario dei dati contesta i nomi dei campi di input del modulo, tieni semplicemente i loro valori giusti per trovare i risultati. vista modulo Intestazione configura il browser per recuperare il tipo di dati dichiarati. Con la libreria delle richieste è facile inviare 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)

Ulteriori informazioni sull'oggetto richiesta: https://requests.readthedocs.io/en/master/api/


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.