How I Built an Amazon Price Tracker

Project Description

I wanted to gift myself a new mobile phone for all the hard work I have done so far. πŸ˜‰ So, I checked Amazon and decided to buy Samsung Galaxy S22 5G. However, the price displayed was beyond my budget and I was eager to wait for the price to drop below a certain threshold. I was confident that the price would fall below this threshold at some point in time. But the problem here was how would I track the price drop on a regular basis.

One option would be to open up my browser every day and keep tracking the price from the page. However, I wanted a smarter way of tracking the price on a daily basis. That is when I came up with an idea to create a script that would not only track the price of the product but also send me an email as soon as the price drops below the threshold price set by me.

Thus, in this project, I will demonstrate how you can create a Python script that monitors the price of a specific product on Amazon and sends an email notification to the user when the price drops below a certain threshold. In the script, we will use several libraries such as “requests” and “BeautifulSoup” to scrape the product’s information from the website and extract the price, and uses “smtplib” and “ssl” to send the email notification.

Let’s us dive into the different steps that will help us to complete this project.

Video Walkthrough

Step 1: Import the Necessary Libraries

Since the task involves scraping, hence I have used the requests and the BeautifulSoup library to scrape the data from the website. Also, we need to send a notification to our email as soon as the price drops below the threshold price. So, we need the help of certain other libraries as well. Let’s go ahead import all these libraries into our script.

import requests
from bs4 import BeautifulSoup as bs
import smtplib
import ssl
from email.message import EmailMessage

Want to learn web scraping with BeautifulSoup? Then try out these tutorials that have detailed explanations of how BeautifulSoup works – “Web Scraping With BeautifulSoup In Python

Step 2: Define the URL and Create the User Agent Info

We begin our script by defining the URL of the product, which in this case is a Samsung Phantom smartphone, as well as a header that is used to make the request to the website. The header contains information about the user-agent, which is used to identify the client making the request. This is done to mimic a real user browsing the website and avoid any detection by Amazon’s servers.

Code:

URL = "https://www.amazon.in/Samsung-Phantom-Storage-Additional-Exchange/dp/B09SH8QD3G/ref=sxin_15_popular-discounts-recommendation_2?content-id=amzn1.sym.575d0a24-9dae-4399-bb81-cd7d74724162%3Aamzn1.sym.575d0a24-9dae-4399-bb81-cd7d74724162&cv_ct_cx=smart%2Bphones%2Bunder%2B30000&keywords=smart%2Bphones%2Bunder%2B30000&pd_rd_i=B09SH8QD3G&pd_rd_r=7803ba47-590e-4112-8f27-faa71c8359ac&pd_rd_w=Hvt1b&pd_rd_wg=ivSHC&pf_rd_p=575d0a24-9dae-4399-bb81-cd7d74724162&pf_rd_r=90MNRZYYSZTAVTR0DQN7&qid=1673934834&sprefix=smart%2Bphones%2Bunder%2B300%2Caps%2C243&sr=1-2-df273b7b-639b-496b-8427-b1aabaae8e8a&th=1"

header = {'User-Agent': 'Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; RM-1152) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15254'}

Step 3: Create the Price Extractor Function

Next we need to create a function that will scrape the price of the product from the webpage.

Code:

def extract_price():
    page = requests.get(URL, headers= header)
    soup = bs(page.content, 'html.parser')
    price = float(soup.find('span', class_='a-price-whole').text.split()[0].replace(',',""))
    return price

The “extract_price” function makes a request to the product’s URL using the “requests” library, and then uses “BeautifulSoup” to parse the HTML content of the page and extract the product’s price. The price is then returned as a float.

Step 4: Create the Email Notifier Function

Then we need a function that will trigger an email notification that will be sent to our email address as soon as the price drops below the threshold/affordable price.

Code:

def notify():
    port = 465  # For SSL
    smtp_server = "smtp.gmail.com"
    sender_email = "coding.champ21@gmail.com"
    receiver_email = "coding.champ21@gmail.com"
    password = 'xxxxxxxxxxxxxx'
    subject = 'BUY NOW!'
    message = f"""
    Price has Dropped! Buy your product now!
    Link: {URL}
              """
    em = EmailMessage()
    em['From'] = sender_email
    em['To'] = receiver_email
    em['Subject'] = subject
    em.set_content(message)
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
        server.login(sender_email, password)
        server.sendmail(sender_email, receiver_email, em.as_string())
        print("Message Sent")

The “notify()” function is used to send an email notification to the user. This function uses “smtplib” and “ssl” to connect to the Gmail SMTP server and send the email. The function takes several parameters such as the sender’s email, the receiver’s email, the email’s subject and message, and the user’s password for the email account. The function also includes a “print” statement that is used to indicate that the email was sent successfully.

Caution: You might get an error while sending the email. In the past, we could connect to Gmail easily using Python just by turning on the β€œLess secure app access” option. But that option is no longer available. Instead, what we have to do now is turn on 2-step verification and then retrieve a 16-character password provided by Google that can be used to log in to Gmail using Python.

To learn more about this, refer to the following article here.

Recommended Read: Receive Automated Email Notification on Website Update

Step 5: Create the Driver Code

Finally, we need our script to define a variable “my_price” and assign it a value. This variable represents the price threshold below which the user wants to be notified. Then our script calls the “extract_price” function and checks if the returned price is less than or equal to “my_price“. If the condition is true, it calls the “notify” function to send an email notification to the email address specified by us previously.

Code:

my_price = 55000
if extract_price() <= my_price:
    notify()

Putting it All Together

We are now ready to put all the bits together and create our final complete code. So, here’s how the final code looks:

Code:

import requests
from bs4 import BeautifulSoup as bs
import smtplib
import ssl
from email.message import EmailMessage

URL = "https://www.amazon.in/Samsung-Phantom-Storage-Additional-Exchange/dp/B09SH8QD3G/ref=sxin_15_popular-discounts-recommendation_2?content-id=amzn1.sym.575d0a24-9dae-4399-bb81-cd7d74724162%3Aamzn1.sym.575d0a24-9dae-4399-bb81-cd7d74724162&cv_ct_cx=smart%2Bphones%2Bunder%2B30000&keywords=smart%2Bphones%2Bunder%2B30000&pd_rd_i=B09SH8QD3G&pd_rd_r=7803ba47-590e-4112-8f27-faa71c8359ac&pd_rd_w=Hvt1b&pd_rd_wg=ivSHC&pf_rd_p=575d0a24-9dae-4399-bb81-cd7d74724162&pf_rd_r=90MNRZYYSZTAVTR0DQN7&qid=1673934834&sprefix=smart%2Bphones%2Bunder%2B300%2Caps%2C243&sr=1-2-df273b7b-639b-496b-8427-b1aabaae8e8a&th=1"

header = {'User-Agent': 'Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; RM-1152) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.15254'}

def extract_price():
    page = requests.get(URL, headers= header)
    soup = bs(page.content, 'html.parser')
    price = float(soup.find('span', class_='a-price-whole').text.split()[0].replace(',',""))
    return price

def notify():
    port = 465  # For SSL
    smtp_server = "smtp.gmail.com"
    sender_email = "coding.champ21@gmail.com"
    receiver_email = "coding.champ21@gmail.com"
    password = 'xxxxxxxxxxxxxx'
    subject = 'BUY NOW!'
    message = f"""
    Price has Dropped! Buy your product now!
    Link: {URL}
              """
    em = EmailMessage()
    em['From'] = sender_email
    em['To'] = receiver_email
    em['Subject'] = subject
    em.set_content(message)
    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
        server.login(sender_email, password)
        server.sendmail(sender_email, receiver_email, em.as_string())
        print("Message Sent")

my_price = 55000
if extract_price() <= my_price:
    notify()

Summary

In short, the script used in this mini-project is a useful tool for monitoring the price of a specific product on Amazon and getting notified when the price drops below a certain threshold. By using the “requests” and “BeautifulSoup” libraries, the script is able to scrape the product’s information from the website and extract the price, and by using the “smtplib” and “ssl” libraries, the script is able to send an email notification to the user. This script can also be modified for other websites and other products or prices as well.

I hope this project added some value to your coding journey. Please subscribe and stay tuned for more interesting solutions and discussions in the future. Happy coding!