Como enviar solicitação POST?

260

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

Mas eu não entendo como usá-lo com PHP ou o que tudo dentro da variável params é ou como usá-lo. Por favor, posso ter uma pequena ajuda para tentar fazer com que isso funcione?

user1113569
fonte
1
A solicitação de publicação é apenas uma solicitação de publicação, independentemente do que está do lado do servidor.
Ondra Žižka
7
Isso envia uma solicitação POST. Em seguida, o servidor responde com 302 cabeçalhos (redirecionado) ao seu POST. O que está realmente errado?
ddinchev
1
Este script não parece python3.2 compat
JDI
O equivalente python3 deste exemplo pode ser: pastebin.com/Rx4yfknM
jdi
1
O que vou sugerir é instalar o live http headeraddon do firefox e abrir o seu URL no firefox e ver o request/responseURL no live http headeraddon do que você entenderá o que params and headersfazer no seu código.
RanRag

Respostas:

388

Se você realmente deseja lidar com HTTP usando Python, recomendo Pedidos: HTTP for Humans . O início rápido do POST adaptado à sua pergunta é:

>>> 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
fonte
Não consigo obter o mesmo resultado que você obteve acima. Escrevi outro número de problema na página e, em seguida, executei o script, mas não consegui ver o número do problema no resultado.
Efe Büyük
2
Altere data = {'número': 12524, para ler dados = {'número': '12524' ,. Eu mesmo teria mudado, mas as edições precisam ter mais de 6 caracteres. Graças
kevthanewversi
2
Como obter o resultado json?
Yohanes AI
9
Se você precisa enviar um objeto JSON que você deve fazer: json={'number': 12524...em vez dedata=...
Seraf
3
por que a resposta diz "Se você realmente deseja lidar com HTTP usando Python"? é uma má idéia lidar com solicitações HTTP? se sim, por que? alguém pode explicar por favor?
Jan Pisl
147

Se você precisa que seu script seja portátil e preferir não ter nenhuma dependência de terceiros, é assim que você envia a solicitação POST exclusivamente no 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)

Saída de amostra:

{
  "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"
}
ainda
fonte
6
Esse código funcionará apenas no Python 3, como eu disse na resposta.
stil 27/01
36

Você não pode obter solicitações POST usando urllib(apenas para GET); tente usar o requestsmódulo, por exemplo:

Exemplo 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

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

Exemplo 1.3:

>>> import json

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

>>> r = requests.post(url, data=json.dumps(payload))
d1jhoni1b
fonte
4
Obrigado. data = json.dumps (payload) é a chave para o meu usecase
Aram
11

Use a requestsbiblioteca para GET, POST, PUT ou DELETE acessando um terminal da API REST. Passe o restante do URL do ponto de extremidade da API url, carga útil (dict) datae o cabeçalho / metadados emheaders

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
fonte
2
Este código tem problemas com o recuo e o nome do parâmetro do cabeçalho.
Xilopaint
2
headersparâmetro está errado e também não temos nenhum json aqui. Devemos usarjson.dumps(pauload)
Arash Hatami
Obrigado @xilopaint e ArashHatami pelo erro de sintaxe. Corrigido agora.
Pranzell
3

Seu dicionário de dados conte os nomes dos campos de entrada do formulário, basta manter os valores corretos para encontrar resultados. Visualização de formulário O cabeçalho configura o navegador para recuperar o tipo de dados que você declara. Com a biblioteca de solicitações, é fácil enviar o 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)

Mais sobre o objeto Request: https://requests.readthedocs.io/en/master/api/

Anastasia Didan
fonte
1

Se você não deseja usar um módulo, você deve instalar como requests, e seu caso de uso é muito básico, então você pode usarurllib2

urllib2.urlopen(url, body)

Consulte a documentação urllib2aqui: https://docs.python.org/2/library/urllib2.html .

Phil
fonte