This is how you do it.

from urllib import request, parse
data = parse.urlencode(<your data dict>).encode()
req =  request.Request(<your url>, data=data) # this will make the method "POST"
resp = request.urlopen(req)
Answer from C Panda on Stack Overflow
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ urllib.request.html
urllib.request โ€” Extensible library for opening URLs โ€” Python ...
Source code: Lib/urllib/request.py The urllib.request module defines functions and classes which help in opening URLs (mostly HTTP) in a complex world โ€” basic and digest authentication, redirection...
๐ŸŒ
Real Python
realpython.com โ€บ urllib-request
Python's urllib.request for HTTP Requests โ€“ Real Python
January 11, 2025 - If youโ€™re looking to make HTTP requests in Python using the built-in urllib.request module, then this tutorial is for you. urllib.request lets you perform HTTP operations without having to add external dependencies. This tutorial covers how to execute GET and POST requests, handle HTTP responses, and even manage character encodings.
๐ŸŒ
ProxiesAPI
proxiesapi.com โ€บ articles โ€บ sending-post-requests-with-python-s-urllib
Sending POST Requests with Python's urllib | ProxiesAPI
February 6, 2024 - data = urllib.parse.urlencode({'name': 'John Smith', 'email': 'john@example.com'}) data = data.encode('ascii') This encodes the data as a URL-encoded string ready for sending. Next we create a request object and specify that it's a POST request:
๐ŸŒ
Python documentation
docs.python.org โ€บ 3 โ€บ howto โ€บ urllib2.html
HOWTO Fetch Internet Resources Using The urllib Package โ€” Python 3.14.3 documentation
Not all POSTs have to come from forms: you can use a POST to transmit arbitrary data to your own application. In the common case of HTML forms, the data needs to be encoded in a standard way, and then passed to the Request object as the data argument. The encoding is done using a function from the urllib.parse library.
๐ŸŒ
Finxter
blog.finxter.com โ€บ home โ€บ learn python blog โ€บ how to send a post request using urllib in python?
How to Send a POST Request Using urllib in Python? - Be on the Right Side of Change
September 29, 2022 - You can use a POST request to send data to a server to create/update a resource. When you send the data to a server using a POST request, the data is stored in the request body of the HTTP request.
Top answer
1 of 7
49

This may have been answered before: Python URLLib / URLLib2 POST.

Your server is likely performing a 302 redirect from http://myserver/post_service to http://myserver/post_service/. When the 302 redirect is performed, the request changes from POST to GET (see Issue 1401). Try changing url to http://myserver/post_service/.

2 of 7
49

Do it in stages, and modify the object, like this:

# make a string with the request type in it:
method = "POST"
# create a handler. you can specify different handlers here (file uploads etc)
# but we go for the default
handler = urllib2.HTTPHandler()
# create an openerdirector instance
opener = urllib2.build_opener(handler)
# build a request
data = urllib.urlencode(dictionary_of_POST_fields_or_None)
request = urllib2.Request(url, data=data)
# add any other information you want
request.add_header("Content-Type",'application/json')
# overload the get method function with a small anonymous function...
request.get_method = lambda: method
# try it; don't forget to catch the result
try:
    connection = opener.open(request)
except urllib2.HTTPError,e:
    connection = e

# check. Substitute with appropriate HTTP code.
if connection.code == 200:
    data = connection.read()
else:
    # handle the error case. connection.read() will still contain data
    # if any was returned, but it probably won't be of any use

This way allows you to extend to making PUT, DELETE, HEAD and OPTIONS requests too, simply by substituting the value of method or even wrapping it up in a function. Depending on what you're trying to do, you may also need a different HTTP handler, e.g. for multi file upload.

Find elsewhere
๐ŸŒ
DEV Community
dev.to โ€บ ultrainstinct05 โ€บ using-the-python-urllib-module-for-making-web-requests-5hkm
Using the python urllib module for making web requests. - DEV Community
December 29, 2019 - Here we pass the url parameter to the Request method defined on urllib.request. We then read the response object and decode it. If you closely inspect the code, we are not specifying anywhere that we intend to make a GET request to the url. The Request method actually takes in several arguments. One of them is the method parameter which is a string that indicates the HTTP request method that will be used. It also takes in a data parameter (which we will talk about when we see POST requests).
๐ŸŒ
Python Programming
pythonprogramming.net โ€บ urllib-tutorial-python-3
Python urllib tutorial for Accessing the Internet
The other is POST, where you send data into the server, like you post some data, and you get a request based on the post. ... You see there are 2 variables here. You can see them because of the equals sign. The first variable is denoted with a question mark, and all of the subsequent ones are ...
๐ŸŒ
DNMTechs
dnmtechs.com โ€บ making-a-post-request-in-python-3-using-urllib
Making a POST Request in Python 3 using urllib โ€“ DNMTechs โ€“ Sharing and Storing Technology Knowledge
We create a Request object with the URL, encoded data, and the HTTP method set to โ€œPOSTโ€. Finally, we use the urlopen function to send the request and receive the response from the server. The response is then printed to the console. The urllib library is widely used in the Python community ...
Top answer
1 of 2
6

HTTP POST works as expected:

#!/usr/bin/env python
from contextlib import closing
try:
    from urllib.parse import urlencode
    from urllib.request import urlopen
except ImportError: # Python 2
    from urllib import urlencode
    from urllib2 import urlopen

url = 'http://httpbin.org/post'
data = urlencode({"field1" : "value", "Submit": "Save"}).encode()
with closing(urlopen(url, data)) as response:
    print(response.read().decode())

You may see GET only after an http redirect (as the rfc recommends -- no data should be posted on redirect without prompting the user).

For example, here's an http server that redirects POST / requests:

#!/usr/bin/env python
from flask import Flask, redirect, request, url_for # $ pip install flask

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        return redirect(url_for('post'))
    return '<form method="POST"><input type="submit">'


@app.route('/post', methods=['GET', 'POST'])
def post():
    return 'Hello redirected %s!' % request.method

if __name__ == '__main__':
    import sys
    port = int(sys.argv[1]) if len(sys.argv) > 1 else None
    app.run(host='localhost', port=port)

Making an HTTP POST request using the same code (urlopen(url, data)) leads to the redirection and the second request is GET:

"POST / HTTP/1.1" 302 -
"GET /post HTTP/1.1" 200 -

Again, the first request is POST, not GET. The behavior is exactly the same if you visit / and click submit button (the browser makes POST request and then GET request).

Python issue: "Document how to forward POST data on redirects" contains a link to HTTPRedirectHandler's subclass that posts data on redirect:

#!/usr/bin/env python
from contextlib import closing
try:
    from urllib.parse import urlencode
    from urllib.request import (HTTPError, HTTPRedirectHandler, Request,
                                build_opener, urlopen)
except ImportError: # Python 2
    from urllib import urlencode
    from urllib2 import (HTTPError, HTTPRedirectHandler, Request,
                         build_opener, urlopen)

class PostHTTPRedirectHandler(HTTPRedirectHandler):
    """Post data on redirect unlike urrlib2.HTTPRedirectHandler."""
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        m = req.get_method()
        if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
            or code in (301, 302, 303) and m == "POST"):
            newurl = newurl.replace(' ', '%20')
            CONTENT_HEADERS = ("content-length", "content-type")
            newheaders = dict((k, v) for k, v in req.headers.items()
                              if k.lower() not in CONTENT_HEADERS)
            return Request(newurl,
                           data=req.data,
                           headers=newheaders,
                           origin_req_host=req.origin_req_host,
                           unverifiable=True)
        else:
            raise HTTPError(req.get_full_url(), code, msg, headers, fp)


urlopen = build_opener(PostHTTPRedirectHandler).open

url = 'http://localhost:5000'
data = urlencode({"field1" : "value", "Submit": "Save"}).encode()
with closing(urlopen(url, data)) as response:
    print(response.read().decode())

The access log shows two POST requests in this case (the second request is POST):

"POST / HTTP/1.1" 302 -
"POST /post HTTP/1.1" 200 -

Note: you could customize the HTTPRedirectHandler to follow the rfc 2616 behavior.

2 of 2
0

OK so i figured out what was wrong. The python module "requests.post" will not perform a post if the url is one that redirects. So I had to put the actual url in for it to work and not a url that would direct me to my desired url.

THis is the same for those using urllib

๐ŸŒ
CyuBlog
cyublog.com โ€บ articles โ€บ python-en โ€บ urllib-request-sample
Python: Use urllib.request to do http request - CyuBlog
May 18, 2021 - In this article, I will show you how to execute HTTP requests with urllib.request. The workflow is, 1. Create a request by `urllib.request.Request` method. 2. Assign the request as a parameter of `urllib.request.urlopen` method to get response. 3. use `json` module to parse the response.
Top answer
1 of 2
2

This would be the equivalent request using the python requests library.

url = "https://api.infermedica.com/dev/parse"
headers = {
    'App_Id': '4c177c',
    'App_Key': '6852599182ba85d70066986ca2b3',
    'Content-Type': 'application/json',
}
data = {'text': 'i feel stomach pain but no coughing today'}

r = requests.post(url, headers=headers, data=json.dumps(data))
print r.status_code
print r.json()

But your real problem is that you're using the wrong header keys for their api. It's App-Id and App-key, not App_Id and App_key. It would look like this:

headers = {
    'App-Id': 'xx', 
    'App-key': 'xxxx', 
    'Accept': 'application/json', 
    'Content-Type': 'application/json',
    'Dev-Mode': 'true'}

data = {'text': 'i feel stomach pain but no coughing today'}
r = requests.post(url, headers=headers, data=json.dumps(data))

Also worth noting, they have a python api that does all this for you.

2 of 2
1

json_data = json.dumps(data) is not the correct way to prepare POST data.

You should use urllib.urlencode() to do the job:

import urllib
data = { "text": text }
req = urllib2.Request(self.url, urllib.urlencode(data), self.headers)
response = urllib2.urlopen(req).read()

Docs:

class urllib2.Request(url[, data][, headers][, origin_req_host][, unverifiable]) This class is an abstraction of a URL request.

data may be a string specifying additional data to send to the server, or None if no such data is needed. Currently HTTP requests are the only ones that use data; the HTTP request will be a POST instead of a GET when the data parameter is provided. data should be a buffer in the standard application/x-www-form-urlencoded format. The urllib.urlencode() function takes a mapping or sequence of 2-tuples and returns a string in this format.

๐ŸŒ
NAO IT Systems LLC.
digibeatrix.com โ€บ home โ€บ apis & external libraries โ€บ complete guide to python urllib: get/post & web scraping
Complete Guide to Python urllib: GET/POST & Web Scraping - Practical Python Programming
November 29, 2025 - Learn Python's urllib for GET/POST requests, URL parsing, web scraping, and API access. A practical, example-driven guide to fetching and extracting web data.
๐ŸŒ
Qubits & Bytes
qubitsandbytes.co.uk โ€บ python โ€บ sending-http-requests-using-pythons-urllib
Sending HTTP Requests Using Python's urllib - Qubits & Bytes
February 15, 2025 - This can then be passed to the Request constructor. urllib refers to this attribute as data. ... When the data attribute is set to a value other than None (which is the default), the request type is automatically changed to POST.
๐ŸŒ
Real Python
realpython.com โ€บ videos โ€บ basic-urllib-request
Perform Basic HTTP Requests With urllib.request (Video) โ€“ Real Python
In this lesson, youโ€™ll learn how to perform basic HTTP requests with urllib.request. Before diving deep into what HTTP request is and how it works, you can start by making a basic GET request to a sample URL. In this case, youโ€™ll make a request toโ€ฆ
Published ย  January 2, 2024
๐ŸŒ
Python Module of the Week
pymotw.com โ€บ 3 โ€บ urllib.request
urllib.request โ€” Network Resource Access
October 8, 2016 - The HTTP method used by the Request changes from GET to POST automatically after the data is added. $ python3 urllib_request_request_post.py Request method : POST OUTGOING DATA: b'q=query+string&foo=bar' SERVER RESPONSE: Client: ('127.0.0.1', 58613) User-agent: PyMOTW (https://pymotw.com/) Path: / Form data: foo=bar q=query string