Wie sende ich eine POST-Anfrage?


260

Ich habe dieses Skript online gefunden:

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

Aber ich verstehe nicht, wie man es mit PHP benutzt oder was alles in der params-Variablen ist oder wie man es benutzt. Kann ich bitte ein wenig Hilfe bei dem Versuch haben, dies zum Laufen zu bringen?


1
Post-Anfrage ist nur Post-Anfrage, unabhängig davon, was sich auf der Serverseite befindet.
Ondra Žižka

7
Dies sendet eine POST-Anfrage. Dann antwortet der Server mit 302 (Weiterleitungs-) Headern auf Ihren POST. Was ist eigentlich falsch?
Ddinchev

1
Dieses Skript sieht nicht python3.2 kompatibel aus
jdi

python3 Äquivalent dieses Beispiel könnte sein: pastebin.com/Rx4yfknM
jdi

1
Was ich vorschlagen werde, ist das Firefox- live http headerAddon zu installieren und dann Ihre URL in Firefox zu öffnen und die request/responseURL im live http headerAddon zu sehen, als Sie verstehen werden, was params and headersin Ihrem Code zu tun ist.
RanRag

Antworten:


388

Wenn Sie wirklich mit HTTP unter Verwendung von Python umgehen möchten, empfehle ich dringend Anfragen: HTTP für Menschen . Der an Ihre Frage angepasste POST-Schnellstart lautet:

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

Ich kann nicht das gleiche Ergebnis erzielen wie oben. Ich habe eine andere Ausgabenummer auf die Seite geschrieben und dann das Skript ausgeführt, aber ich konnte die Ausgabenummer im Ergebnis nicht sehen.
Efe Büyük

2
Bitte ändern Sie data = {'number': 12524, um data = {'number': '12524' zu lesen. Ich hätte es selbst geändert, aber die Änderungen müssen mehr als 6 Zeichen umfassen. Danke
kevthanewversi

2
Wie bekomme ich ein JSON-Ergebnis?
Yohanes AI

9
Wenn Sie ein JSON-Objekt senden müssen, sollten Sie Folgendes tun: json={'number': 12524...anstelle vondata=...
Seraf

3
Warum lautet die Antwort "Wenn Sie wirklich mit HTTP mit Python umgehen möchten"? Ist es eine schlechte Idee, HTTP-Anfragen zu bearbeiten? Wenn ja warum? kann mir bitte jemand erklären
Jan Pisl

147

Wenn Sie möchten, dass Ihr Skript portabel ist und Sie keine Abhängigkeiten von Drittanbietern haben möchten, senden Sie die POST-Anforderung auf diese Weise ausschließlich 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)

Beispielausgabe:

{
  "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
Dieser Code funktioniert nur in Python 3, wie ich in der Antwort gesagt habe.
stil

36

Sie können POST-Anforderungen nicht mit urllib(nur für GET) erreichen, sondern versuchen, ein requestsModul zu verwenden, z.

Beispiel 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

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

Beispiel 1.3:

>>> import json

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

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

4
Vielen Dank. data = json.dumps (payload) ist der Schlüssel für meinen Anwendungsfall
Aram

11

Verwenden Sie die requestsBibliothek, um durch Erreichen eines REST-API-Endpunkts GET, POST, PUT oder DELETE zu erhalten. Übergeben Sie die URL des restlichen API-Endpunkts url, Payload (dict) dataund Header / Metadatenheaders

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
Dieser Code hat Probleme mit dem Einzug und dem Namen des Header-Parameters.
Xilopaint

2
headersParameter ist falsch und wir haben hier auch keinen JSON. Wir sollten verwendenjson.dumps(pauload)
Arash Hatami

Vielen Dank an @xilopaint und ArashHatami für den Syntaxfehler. Jetzt korrigiert.
Pranzell

3

Ihr Datenwörterbuch enthält Namen von Formulareingabefeldern. Sie behalten nur deren Werte bei, um Ergebnisse zu finden. Formularansicht Header konfiguriert den Browser so, dass er den von Ihnen deklarierten Datentyp abruft. Mit der Anforderungsbibliothek ist es einfach, POST zu senden:

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)

Weitere Informationen zum Anforderungsobjekt: https://requests.readthedocs.io/en/master/api/


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.