Never Fill Out Another Boring Online Form. Use Python to make it automatic!
Tags: python, data, automation
Published: 2023-06-19 20:00:03

![text](https://github.com/apotitech/photos_document_md/raw/master/src/common/photos/forms.PNG "text")

Nowadays, everyone wants your data, so if you want to open a new account, enter a promotion, or acquire a free e-book, you must fill out a form with your information.

This isn't a big concern if you only do it once, but it becomes monotonous if you have to repeat the same processes often, therefore the ideal answer is to automate it with **Python**🐍.


Let's use Python to automate the filling out of web forms. We'll start by seeing how to fill out a form with data from a Python list, and then I'll show you how to make phoney data to fill out several forms.

# How to Use Python to Automate Web Form Filling

To automate web forms with Python, we'll utilise the Selenium library. To install it, follow the steps below.

All of the Selenium methods covered in this book can be found in my Automation Cheatsheet (free PDF).

## 1. Set up Selenium
Open a terminal and type the following command to install Selenium.

```
pip install selenium
```

This will install Selenium 4, which is the version we'll be using in this tutorial.

Then we must obtain chromedriver:

- Verify your Google Chrome version (on Chrome, click the three dots, then "help," and then "about Google Chrome").
- Download the correct Chromedriver here (you must download the Chromedriver file again after any Chrome upgrade).
- Unzip the driver and copy the location of the Chromedriver file.

## 2. Completing Google Forms
Let's get started by importing the libraries we'll be using for this automation.

```
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time
```
Then we create a `path` to our chromedriver file, the website we want to automate, and a `driver` that will allow us to communicate with the website using Selenium.

**Website**: For this easy demo, we'll utilize the "Contact Information" template from Google Form, which you can get [here](https://forms.gle/GRgxTrG8FfXUCLE99). 

Make sure you **copy** the link.

If the link breaks or has stopped working, <a href="https://www.google.com/forms/about/" target="_blank">go to Google Forms</a> and use the template below to create your own form with your own link.

![text](https://github.com/apotitech/photos_document_md/raw/master/src/common/photos/forms2.PNG "text")

**Note**: If you create your own form, make sure to **uncheck or turn off** the "**Limit to 1 response**" option in **Settings** so that we can fill out as many forms as we want.

Here are the **variables** we make to get started with Selenium.

```
path = '/Users/.../chromedriver' # paste your path here
service = Service(executable_path=path)
website = 'https://forms.gle/GRgxTrG8FfXUCLE99' # paste your link
driver = webdriver.Chrome(service=service)
```
After that, we use the `driver.get()` function to open the website using Selenium.

```
driver.get(website)
```
We also add a wait or delay to allow the webpage to load all of the information. To do this, we import the `time` module.

```
import time
time.sleep(3) # 3 seconds delay
```
The code should now look something like this:

```
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time
import pandas as pd

path = '/Users/.../chromedriver'  # your path
service = Service(executable_path=path)
website =  # your link
driver = webdriver.Chrome(service=service)

driver.get(website)
time.sleep(3)
```
To fill in the information with Selenium, we must first inspect the website. 

Examine the "**Name**" field. To do this, right-click on any empty section in the first block of the webpage and select "**Inspect**".

![text](https://github.com/apotitech/photos_document_md/raw/master/src/common/photos/forms3.PNG "text")

This option is available in all recent web browsers. It will open **Developer tools** window on the **right side of your screen**. 

>**What you see there is the website's HTML content.**

Regardless of the element that is highlighted on your computer, we'll use the one with the `data-params` attribute name because it contains the field name (e.g., Name, Email, Address, Phone number, Comments), taht we are looking for.

![text](https://github.com/apotitech/photos_document_md/raw/master/src/common/photos/forms4.PNG "text")

Let's now create the XPath for the "**Name**" field. The syntax of an XPath is as follows:

![text](https://github.com/apotitech/photos_document_md/raw/master/src/common/photos/forms5.PNG "text")

Furthermore, we will use the `contains()` function, therefore our XPath will be:

```
//div[contains(@data-params, "Name")]
```
We must now examine the field where the placeholder "**Your answer**" is positioned.

Unlike other websites, Google Form maintains an inconsistent pattern in which some fields, such as "**Email**," have the `<input>` tag but others, such as "**Address**," have the `<textarea>` tag.

![text](https://github.com/apotitech/photos_document_md/raw/master/src/common/photos/forms6.gif "text")

The final XPath of the field with the "**Your answer**" placeholder will differ for those with the `<input>` and `<textarea>` tags.

```
//div[contains(@data-params, "Name")]//textarea //div[contains(@data-params, "Name")]//input
```
To connect them, we'll use the "**or**" conditional `|`
```bash
//div[contains(@data-params, "Name")]//textarea | //div[contains(@data-params, "Name")]//input
```

To fill in the data, we will use the `.find_element` and `.send_keys` functions.

```
text_input = driver.find_element(by='xpath',
                                 value='//div[contains(@data-params, "Name")]//textarea | '
                                       '//div[contains(@data-params, "Name")]//input')
text_input.send_keys("Write your text here")
```
## 3. Using fake data, create a list and fill in all of the fields.

There are other Python tools, such as `faker`, that can help us generate fake data (I'll show you how faker works at the end), but to keep things simple, let's construct data in a list ourselves and then store it in a dictionary.

```
fields = ['Name', 'Email', 'Address', 'Phone number', 'Comments']
data = ['Frank', 'frank@example.com', '123 St', '987654321', 'Hello World']
my_form = dict(zip(fields, data))
```
To populate this data into all of our form's fields, we use the `.find_element` and `.send_keys` functions inside a for loop.
```bash
for field, data in my_form.items():
    text_input = driver.find_element(by='xpath',
                                     value=f'//div[contains(@data-params, "{field}")]//textarea | '
                                           f'//div[contains(@data-params, "{field}")]//input')
    text_input.send_keys(data)
```
## 4. Submit the form.
We are almost done. Next, we have to click on the "**Submit**" button.

![text](https://github.com/apotitech/photos_document_md/raw/master/src/common/photos/forms7.PNG "text")

Using Selenium, we inspect the button to generate its XPath before using the `.click` method to actually click on the "**Submit**" button.
```
submit_button = driver.find_element(by='xpath',
                                    value='//div[@role="button"]//span[text()="Submit"]')
submit_button.click()
```
Note: If you have your browser set to another language, the value inside the `text()` attribute will most likely be in that language. For example, because my browser is in Spanish, I must change a portion of the XPath to `//span[text()="Enviar"]`.

**Here's the code we have written so far.**

```
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time

path = '/Users/.../chromedriver'  # your path goes here
service = Service(executable_path=path)
website =  # your link goes here
driver = webdriver.Chrome(service=service)

fields = ['Name', 'Email', 'Address', 'Phone number', 'Comments']
data = ['Frank', 'frank@example.com', '123 St', '987654321', 'Hello World']
my_form = dict(zip(fields, data))

driver.get(website)
time.sleep(3)

for field, data in my_form.items():
    text_input = driver.find_element(by='xpath',
                                     value=f'//div[contains(@data-params, "{field}")]//textarea | '
                                           f'//div[contains(@data-params, "{field}")]//input')
    text_input.send_keys(data)

submit_button = driver.find_element(by='xpath', value='//div[@role="button"]//span[text()="Submit"]')
submit_button.click()

time.sleep(1)
driver.quit()
```

Yay!👏 Congratulations, you now understand how to fill out web forms automatically using 🐍. 

> You can now take this a step further by submitting hundreds of forms with fictitious data.

# Conclusion

Now that you understand the fundamentals, you may skip ahead to minute 13:26 of my video below to discover how to produce fictitious data and submit hundreds of forms with Python.

For more information and a detailed video of automating filing forms with data, click here.

That is all for today! 👋

> Thank you for taking the time to read this! If you like the article, please clap (up to 50 times!) and connect with me on [LinkedIn](https://www.linkedin.com/in/apotitech-b79097210/) and [Medium](https://medium.com/@softwaresennin) to remain up to speed on my future articles. 😅