Creating a Python Bot with Selenium

In this post, I’m going to show you how to create a basic bot that’s capable of automating just about any mundane task you need done!

Advertisements

What can this bot do?

This kind of bot will have such a wide range of possibilities because it is going to be able to do most anything that YOU can do inside of a web browser. To give you some ideas of what you could use this bot for, I’ve put together a list of popular potential use cases:

  • Scraping information from the web
  • Monitoring a store page and purchasing an item when it comes in stock
  • Paying your bills
  • Sending emails
  • Playing chess
  • Most anything you can do in a browser!

We need a specific case to learn with as an example though, so I’ll show you how to code a bot to monitor an out-of-stock product on BestBuy.com, and then purchase that item when it becomes available.

Planning

Before we get into the weeds with the code, let’s discuss the planning phase. This is a fairly complex job; our bot needs to be able to walk through all of the same steps that a human would perform in a web browser to complete the same task… and we go through a lot of these steps subconsciously! We need to understand what’s necessary to accomplish our end goal on a more granular level so that we know what to tell the bot to do, and when to do it.

So, let’s map out the series of individual steps that need to happen in order for this to work:

  1. Login to BestBuy.com
  2. Visit product page
  3. Check if product is available
  4. If product is not available, wait X amount of time until refresh
  5. If product is available, purchase item
  6. Walk through steps of purchasing item with card that is already saved to BestBuy account.
  7. If purchase was not successful, loop back to step 3.
  8. If purchase was successful, end
Advertisements

Code

import time
import sys
from datetime import datetime
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
'''
This bot makes a few assumptions:
– You have a payment method already setup
– You have a valid shipping address already setup
– You won't encounter any popups/additiona login checks
– If this happens, you will need to modify the code to handle this
'''
def main(wait_time, product, cvv):
# Initialize Browser
profile = webdriver.FirefoxProfile()
profile.set_preference('general.useragent.override',
'Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0')
browser = webdriver.Firefox(profile)
# Navigate to target website and wait for user to login
browser.get("https://www.bestbuy.com/")
input('When you are logged into BestBuy press ENTER to continue.')
# After user has logged in, navigate to the product that we
# want to try and purchase
browser.get(product)
# Loop until we're able to purchase the product
complete = False
while (not complete):
# Use a try/catch to help determine if purchase was successful
# We expect that Selenium will throw exceptions if
# any element does not exist.
try:
addToCartElement = browser.find_element_by_xpath(
"//button[@class='c-button c-button-primary c-button-lg c-button-block c-button-icon c-button-icon-leading add-to-cart-button']")
addToCartElement.click()
browser.get('https://www.bestbuy.com/cart')
cartCheckoutElement = browser.find_element_by_xpath(
"//button[@class='btn btn-lg btn-block btn-primary']")
cartCheckoutElement.click()
freeShippingRadioElement = browser.find_element_by_xpath(
"//input[@id='fulfillment-shipping-4tqhbezgfdmgc-4sm0ivsy5jjyi']")
freeShippingRadioElement.click()
cvvElement = browser.find_element_by_xpath("//input[@id='cvv']")
cvvElement.sendKeys(cvv)
placeOrderElement = browser.find_element_by_xpath(
"//button[@class='btn btn-lg btn-block btn-primary button__fast-track']")
placeOrderElement.click()
complete = True
# Handle the expected exception by printing useful information and waiting
# before trying again
except NoSuchElementException:
print('[' + str(datetime.now()) + '] Not in stock… waiting ' +
str(wait_time) + ' seconds…')
time.sleep(wait_time)
browser.get(product)
# Gracefully end if the user ends the bot with CTRL+C
except KeyboardInterrupt:
print("Shutting down bot…")
break
# Gracefully end if any unexpected exception occurs
# Output exception to screen.
except Exception as ex:
print(str(ex))
break
if __name__ == '__main__':
if len(sys.argv) < 4:
sys.exit(
f'Usage: python3 {sys.argv[0]} <WAIT_TIME_IN_SECONDS> <BESTBUY_PRODUCT_WEB_URL> <CVV>')
wait_time = int(sys.argv[1])
product = str(sys.argv[2])
cvv = str(sys.argv[3])
main(wait_time, product, cvv)
view raw Bot.py hosted with ❤ by GitHub

Running the Code

You can run the code using the following:
python3 Bot.py <TIME_IN_SECONDS> <BESTBUY_PRODUCT_WEB_URL> <CVV>

Example:
python3 Bot.py 10 https://www.bestbuy.com/site/evga-rtx-3080-xc3-ultra-gaming-10g-p5-3885-kh-pci-express-4-0-lhr/6471615.p?skuId=6471615 1234

The previous command will point our bot to the provided product page. If the product is out of stock, the bot will wait 10 seconds before checking again. If the product is in stock, then the bot will proceed to purchase the item. To do this, it will have to enter 1234 into the expected CVV field for the card that you have already setup with your BestBuy account.

Advertisements

Troubleshooting

This code relies on several assumptions:

  • The customer account is setup with a valid payment method
  • The account is setup with a valid shipping address
  • The browser will not encounter any additional login checks
  • The browser will not encounter any popups
  • BestBuy has not updated their website since this code was made

If popups or additional checks do occur, you should be able modify the code to take these into account. For example, BestBuy likes to throw survey popups for users. If this happens, you can add to the code to have it check for the presence of a popup, and then have it click the “X” in the top right based on its path if there is one.

Learn More

If you enjoyed this, consider following me here on WordPress or over on Medium! I write a new post every week and I would really appreciate your support. Here are a few of my previous posts that you may also be interested in:

Buy me a cup of coffee!

As always, if you liked what you read and you’d like to support me, please consider buying me some coffee! Every cup of coffee sent my way helps me stay awake after my full-time job so that I can produce more high quality blog posts! Any and all support would be greatly appreciated!

Ballad Serial — Trans Arsonist Art Network
Advertisement

6 thoughts on “Creating a Python Bot with Selenium

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s