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?

user1113569
quelle
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...
>>> 
Parkerfath
quelle
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"
}
Stil
quelle
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))
d1jhoni1b
quelle
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
Pranzell
quelle
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/

Anastasia Didan
quelle
1

Wenn Sie kein Modul verwenden möchten, das Sie wie installieren möchten requests, und Ihr Anwendungsfall sehr einfach ist, können Sie es verwendenurllib2

urllib2.urlopen(url, body)

Siehe die Dokumentation urllib2hier: https://docs.python.org/2/library/urllib2.html .

Phil
quelle