Як надіслати POST-запит?


260

Я знайшов цей сценарій в Інтернеті:

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

Але я не розумію, як його використовувати з PHP або що все, що знаходиться всередині змінної params, або як ним користуватися. Чи можу я, будь ласка, трохи допомогти у спробі налагодити це?


1
Запит на пошту - це просто запит на пошту, незалежно від того, що знаходиться на стороні сервера.
Ondra Žižka

7
Це надсилає запит POST. Тоді сервер відповідає 302 (перенаправлення) заголовками на ваш POST. Що насправді не так?
ддінчев

1
Цей сценарій не виглядає співзвучним python3.2
jdi

Еквівалентом цього прикладу python3 може бути: pastebin.com/Rx4yfknM
jdi

1
Що я запропоную, - встановити live http headerаддон Firefox, а потім відкрити URL-адресу у firefox і побачити request/responseURL-адресу в live http headerаддоні, ніж ви зрозумієте, що params and headersробити у своєму коді.
RanRag

Відповіді:


388

Якщо ви дійсно хочете працювати з HTTP за допомогою Python, я настійно рекомендую Запити: HTTP для людей . Швидкий старт POST, адаптований до вашого питання:

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

Я не можу отримати такий самий результат, як ти. Я написав ще один номер випуску на сторінці, а потім запустив сценарій, але не міг побачити номер випуску в результаті.
Ефе Бююк

2
Будь ласка, змініть дані = {'число': 12524, щоб прочитати дані = {'число': '12524' ,. Я сам би змінив це, але правки повинні містити більше 6 символів. Дякую
kevthanewversi

2
Як отримати результат json?
Йоханес AI

9
Якщо вам потрібно надіслати об’єкт JSON, вам слід зробити це: json={'number': 12524...замістьdata=...
Серафа

3
чому відповідь говорить "Якщо ви дійсно хочете працювати з HTTP за допомогою Python"? чи погана ідея обробляти HTTP-запити? якщо так, то чому? хтось може пояснити, будь ласка?
Ян Післ

147

Якщо вам потрібен, щоб ваш скрипт був переносним, і ви, швидше, не мали б сторонніх залежностей, саме так ви надсилаєте POST-запит виключно на 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)

Вибірка зразка:

{
  "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
Цей код буде працювати лише в Python 3, як я вже сказав у відповіді.
стиль

36

Ви не можете досягти запитів POST, використовуючи urllib(тільки для GET), натомість спробуйте використовувати requestsмодуль, наприклад:

Приклад 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

Приклад 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"
  },
  ...
}

Приклад 1.3:

>>> import json

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

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

4
Дякую. data = json.dumps (корисний вантаж) - це ключ для моєї корисної справи
Aram

11

Використовуйте requestsбібліотеку для GET, POST, PUT або DELETE, натиснувши кінцеву точку REST API. Передайте інший URL-адресу кінцевої точки api url, корисне навантаження (dict) у dataта заголовок / метадані вheaders

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
Цей код має проблеми з відступом та назвою парамєнта заголовка.
xilopaint

2
headersпараметр неправильний, і ми також не маємо жодного json тут. Ми повинні використовуватиjson.dumps(pauload)
Arash Hatami

Дякуємо @xilopaint та ArashHatami за синтаксичну помилку. Виправлено зараз.
Пранцелл

3

У вашому словнику даних містяться назви полів введення форми, ви просто тримаєте право їх значення, щоб знайти результати. Перегляд форми Header налаштовує браузер для отримання типу даних, які ви оголошуєте. З бібліотекою запитів надіслати пошту легко:

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)

Більше про об’єкт Запит: https://requests.readthedocs.io/en/master/api/


1

Якщо ви не хочете використовувати модуль, який вам належить встановити requests, і ваш випадок використання є дуже простим, ви можете використовувати йогоurllib2

urllib2.urlopen(url, body)

Дивіться документацію urllib2тут: https://docs.python.org/2/library/urllib2.html .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.