337

I found this 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()

But I don't understand how to use it with PHP or what everything inside the params variable is or how to use it. Can I please have a little help with trying to get this to work?

jps
22.9k18 gold badges93 silver badges121 bronze badges
asked Jul 4, 2012 at 4:30
6
  • 1
    Post request is just post request, regardless what's on server side. Commented Jul 4, 2012 at 4:35
  • 8
    This sends a POST request. Then the server responds with 302 (redirect) headers to your POST. What is actually wrong? Commented Jul 4, 2012 at 4:41
  • 1
    This script doesn't look python3.2 compat Commented Jul 4, 2012 at 5:10
  • python3 equivalent of this example might be: pastebin.com/Rx4yfknM Commented Jul 4, 2012 at 5:39
  • 1
    What I will suggest is install firefox's live http header addon and than open your url in firefox and see the request/response of url in live http header addon than you will understand what params and headers do in your code. Commented Jul 4, 2012 at 6:48

7 Answers 7

496

If you really want to handle with HTTP using Python, I highly recommend Requests: HTTP for Humans. The POST quickstart adapted to your question is:

>>> 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...
>>> 
Brōtsyorfuzthrāx
4,8095 gold badges43 silver badges59 bronze badges
answered Jul 4, 2012 at 8:08
Sign up to request clarification or add additional context in comments.

7 Comments

I cannot get the same result as you did above. I wrote another issue number on the page and then run the script but I could not see the Issue number on the result.
for the record: a working code recently for me, data={'@number': '12524', '@type': 'issue', '@action': 'show'}
How to get json result?
If you need to send a JSON object you should do: json={'number': 12524... instead of data=...
why does the answer say "If you really want to handle with HTTP using Python"? is it a bad idea to handle HTTP requests? if so, why? can anyone explain please?
|
191

This is a solution without any external pip dependencies, but works only in Python 3+ (Python 2 won't work):

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())
with urlopen(request) as response:
 json = response.read().decode()
print(json)

Sample output:

{
 "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"
}
Klesun
14.1k7 gold badges66 silver badges60 bronze badges
answered Apr 17, 2016 at 15:30

Comments

39

You can't achieve POST requests using urllib (only for GET), instead try using requests module, e.g.:

Example 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

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

Example 1.3:

>>> import json
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, data=json.dumps(payload))
waterproof
5,1935 gold badges34 silver badges31 bronze badges
answered Apr 10, 2016 at 7:49

2 Comments

Thanks. data=json.dumps(payload) is the key for my usecase
replace "data" with "json" would also do the trick
24

Use requests library to GET, POST, PUT or DELETE by hitting a REST API endpoint. Pass the rest api endpoint url in url, payload(dict) in data and header/metadata in 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)
Pikamander2
8,4504 gold badges58 silver badges75 bronze badges
answered Dec 5, 2018 at 8:38

3 Comments

This code has issues with indentation and the header param name.
headers parameter is wrong and also we have not any json here. We should use json.dumps(pauload)
Thanks @xilopaint and ArashHatami for the syntax error. Corrected now.
6

Your data dictionary conteines names of form input fields, you just keep on right their values to find results. form view Header configures browser to retrieve type of data you declare. With requests library it's easy to send 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)

More about Request object: https://requests.readthedocs.io/en/master/api/

answered Jan 20, 2020 at 14:28

Comments

3

If you don't want to use a module you have to install like requests, and your use case is very basic, then you can use urllib2

urllib2.urlopen(url, body)

See the documentation for urllib2 here: https://docs.python.org/2/library/urllib2.html.

answered Jan 17, 2019 at 20:17

Comments

3

You can use the request library to make a post request. If you have a JSON string in the payload you can use json.dumps(payload) which is the expected form of payload.


 import requests, json
 url = "http://bugs.python.org/test"
 payload={
 "data1":1234,'data2':'test'
 }
 headers = {
 'Content-Type': 'application/json'
 }
 response = requests.post(url, headers=headers, data=json.dumps(payload))
 print(response.text , response.status_code)
dejanualex
4,4146 gold badges30 silver badges43 bronze badges
answered Sep 10, 2021 at 2:38

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.