Handling forms with urllib

When working with forms, it is useful to use the POST method to send data to the server. The POST method is used for submitting user input from HTML forms and for uploading files to a server.

When using POST, the data that we wish to send will go in the body of the request. We can put any bytes data in there and declare its type by adding a Content-Type header to our request with an appropriate MIME type.

Let's look at an example for sending some HTML form data to a server by using a POST request, just as browsers do when we submit a form on a website. The site at https://httpbin.org offers a test server that returns certain data from requests. It will be used to exemplify some uses of the Requests module.

In the following example, we are using the form that corresponds with a POST method, http://httpbin.org/forms/post.

Suppose we have a service to register an order from a customer, where they must enter information such as their name, phone, email, and the desired pizza size:

This information would be passed through the data attribute through a dictionary structure. The POST method requires an extra field called data, in which we send a dictionary with all the elements that we will send to the server through the corresponding method.

The form data always consists of key-value pairs; urllib lets us work with regular dictionaries to supply the form data. We can create a data dictionary with the customer data, adding information such as their name, telephone, pizza size, and email address with the keys custnamecusttel, size, and custemail respectively:

>>> data_dictionary = {'custname': 'customer','custtel': '323232', 'size': 'large','custemail': '[email protected]'}

When posting the HTML form data, the form values must be formatted in the same way as query strings are formatted in a URL, and must be URL encoded. A Content-Type header must also be set to the special MIME type of application/x-www-form-urlencoded.

In the Request Headerswe can see the Content-Type value when we send data with the POST method:

Since this format is identical to query strings, we can just use the urlencode() function in our dictionary to prepare the data:

>>> data = urlencode(data_dictionary).encode('utf-8')
b'custname=customer&custtel=323232&size=large&custemail=email%40domain.com'

Here, we also additionally encode the result to bytes, as it will be sent as the body of the request. In this case, we use the UTF-8 character set.

Next, we will construct our request:

>>> from urllib.request import Request
>>> req = Request('http://httpbin.org/post',data=data)

By adding our data as the data keyword argument, we are telling urllib that we want our data to be sent as the body of the request. This will make the request use the POST method, rather than the GET method. Next, we add the Content-Type header:

>>> req.add_header('Content-Type', 'application/x-www-form-urlencode;charset=UTF-8')

Lastly, we submit the request and transform the response in a JSON dictionary with the json module.

In the response dictionary, we can see the data and 'Content-Type' we established in the request:

>>> response = urlopen(req)
>>> response_dictionary = json.load(response)
>>> print(response_dictionary)
{'args': {}, 'data': 'custname=customer&custtel=323232&size=large&custemail=email%40domain.com', 'files': {}, 'form': {}, 'headers': {'Accept-Encoding': 'identity', 'Connection': 'close', 'Content-Length': '72', 'Content-Type': 'application/x-www-form-urlencode;charset=UTF-8', 'Host': 'httpbin.org', 'User-Agent': 'Python-urllib/3.6'}, '
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset