Jak wysłać żądanie POST?

260

Znalazłem ten skrypt 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()

Ale nie rozumiem, jak używać go z PHP ani czym jest wszystko w zmiennej params, ani jak jej używać. Czy mogę prosić o pomoc w staraniu się, aby to zadziałało?

użytkownik1113569
źródło
1
Żądanie wysyłania jest tylko żądaniem wysyłania, niezależnie od tego, co jest po stronie serwera.
Ondra Žižka
7
To wysyła żądanie POST. Następnie serwer odpowiada 302 (przekierowaniem) nagłówkami na twój test POST. Co właściwie jest nie tak?
ddinchev
1
Ten skrypt nie wygląda na
zgodnego z Python3.2
odpowiednikiem tego przykładu w python3 może być: pastebin.com/Rx4yfknM
jdi
1
To, co zasugeruję, to zainstalowanie live http headerdodatku do firefoxa, a następnie otwarcie adresu URL w firefoxie i zobaczenie request/responseadresu URL w live http headerdodatku, niż zrozumiesz, co params and headersrobisz w kodzie.
RanRag

Odpowiedzi:

388

Jeśli naprawdę chcesz obsługiwać HTTP za pomocą Pythona, bardzo polecam Requests: HTTP for Humans . Szybki start POST dostosowany do twojego pytania to:

>>> 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
źródło
Nie mogę uzyskać takiego samego wyniku jak ty powyżej. Napisałem inny numer problemu na stronie, a następnie uruchomiłem skrypt, ale nie widziałem numeru problemu na wyniku.
Efe Büyük
2
Zmień dane = {„liczba”: 12524, aby odczytać dane = {„liczba”: „12524” ,. Sam bym to zmienił, ale zmiany muszą zawierać więcej niż 6 znaków. Dzięki
kevthanewversi
2
Jak uzyskać wynik JSON?
Yohanes AI
9
Jeśli chcesz wysłać obiekt JSON, powinieneś zrobić: json={'number': 12524...zamiastdata=...
Seraf
3
dlaczego odpowiedź brzmi „Jeśli naprawdę chcesz obsługiwać HTTP za pomocą Pythona”? czy to zły pomysł na obsługę żądań HTTP? jeśli tak to dlaczego? czy ktoś może wyjaśnić, proszę?
Jan Pisl
147

Jeśli potrzebujesz, aby twój skrypt był przenośny i wolałbyś nie mieć żadnych zewnętrznych zależności, w ten sposób wysyłasz żądanie POST wyłącznie w Pythonie 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)

Przykładowe dane wyjściowe:

{
  "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"
}
stil
źródło
6
Ten kod będzie działał tylko w Pythonie 3, tak jak powiedziałem w odpowiedzi.
stil
36

Nie możesz osiągnąć żądań POST przy użyciu urllib(tylko dla GET), zamiast tego spróbuj użyć requestsmodułu, np .:

Przykład 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

Przykład 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"
  },
  ...
}

Przykład 1.3:

>>> import json

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

>>> r = requests.post(url, data=json.dumps(payload))
d1jhoni1b
źródło
4
Dzięki. data = json.dumps (ładunek) jest kluczem do mojej skrzynki użytkownika
Aram
11

Użyj requestsbiblioteki, aby GET, POST, PUT lub DELETE, naciskając punkt końcowy interfejsu API REST. Przekaż resztę adresu URL punktu końcowego interfejsu API url, ładunek (dict) datai nagłówek / metadane wheaders

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
źródło
2
Ten kod ma problemy z wcięciem i nazwą parametru nagłówka.
xilopaint,
2
headersparametr jest niepoprawny, a także nie mamy tutaj żadnego jsona. Powinniśmy użyćjson.dumps(pauload)
Arash Hatami
Dzięki @xilopaint i ArashHatami za błąd składniowy. Poprawione teraz.
Pranzell,
3

Twój słownik danych zawiera nazwy pól wejściowych formularza, po prostu trzymaj się ich wartości, aby znaleźć wyniki. widok formularza Nagłówek konfiguruje przeglądarkę do pobierania deklarowanych danych. Z biblioteką żądań łatwo jest wysłać 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)

Więcej informacji o obiekcie żądania: https://requests.readthedocs.io/en/master/api/

Anastasia Didan
źródło
1

Jeśli nie chcesz używać modułu, który musisz zainstalować requests, a Twój przypadek użycia jest bardzo prosty, możesz go użyćurllib2

urllib2.urlopen(url, body)

Zobacz dokumentację urllib2tutaj: https://docs.python.org/2/library/urllib2.html .

Phil
źródło