Context

Due to Covid-19 and the following lockdowns, every gym had to close leaving behind tons of practitioners.
These changes involved for a lot of them to find an alternative way to continue working out at home. This is how the “Home Gym” enter the arena.
With thousands of gym adepts determined and as much as gym products available online. The war was inevitable.

On my side, I was working out in a street park nearby and as I progressed (especially on weighted pull-ups) the need to buy more weight plates was felt.
At first, I naively tried to look at stocks on Decathlon and maybe buy some when available.

I did this 3 days having as only result:

Empty stock on Decathlon

After those unsuccessful tries I decided to automate my process and create a little program in Python to notify me when weight plates I need are available.

Script

import datetime
import os
from bs4 import BeautifulSoup
import requests

headers = {
    "user-agent": "curl/7.74.0",
    "Host": "www.decathlon.fr",
    "accept": "*/*"
}

url = "https://www.decathlon.fr/p/disque-de-fonte-musculation-28-mm/_/R-p-7278?mc=1042303"

r = requests.get(url, headers=headers)

needed = [5.0, 10.0]

soup = BeautifulSoup(r.text, 'html.parser')

for item in soup.find_all("li", class_="sizes__size"):
    size = float(item.find("span", class_="sizes__info").get_text().split(" KG")[0].replace(",", "."))
    available = int(item['data-available-quantity'])
    now = datetime.datetime.now()
    time = "{:02d}h{:02d}".format(now.hour, now.minute)

    if size in needed and available > 0:
        os.system("notify-send --urgency critical \"Decathlon at {}\" \"{} items available for {} kg\"".format(time, available, size))

Full script will be explained below.

What this basically does is sending a notification when items are available:

Empty stock on Decathlon
headers = {
    "user-agent": "curl/7.74.0",
    "Host": "www.decathlon.fr",
    "accept": "*/*"
}

url = "https://www.decathlon.fr/p/disque-de-fonte-musculation-28-mm/_/R-p-7278?mc=1042303"

r = requests.get(url, headers=headers)

These lines prepare the HTTP request, send the request and store the response in the r variable.

needed = [5.0, 10.0]

This array contains the differents weights you need to buy. So here I needed 5kg and 10kg weight plates.

soup = BeautifulSoup(r.text, 'html.parser')

Here we instantiate a BeautifulSoup object in the soup variable.

BeautifulSoup is a python library which allow us to parse HTML pages. To use it, we pass the string we need to parse and specify which parser (XML or HTML).

for item in soup.find_all("li", class_="sizes__size"):
    size = float(item.find("span", class_="sizes__info").get_text().split(" KG")[0].replace(",", "."))
    available = int(item['data-available-quantity'])
    now = datetime.datetime.now()
    time = "{:02d}h{:02d}".format(now.hour, now.minute)

    if size in needed and available > 0:
        os.system("notify-send --urgency critical \"Decathlon at {}\" \"{} items available for {} kg\"".format(time, available, size))

Time to core part now! Inspecting the element displaying all weights (the screenshot above) we see that it is structured as a list <li> and has for class sizes__size.

Knowing this we then run through those items and store the quantity available for each item. The quantity here is stored as an attribute called data-available-quantity.

Finally, we check the size of the current item is corresponding to one of our needed weights (5.0 or 10.0 kg) and is available, if it is we send a notification on our desktop informing us about this availability.

How to run it ?

This might sound like a stupid question but, we need to make it run often enough to be in the first people buying the weight plates.
Here comes the handy cron. Setting up a daemon like Cronie we can update the crontab file which specify what to run and how often.
To help you create your own scheduling you can use Crontab guru.

* * * * * /usr/bin/python /path/to/script.py

This means, execute with python the script decath-stock-notifier.py at every minute.

Here it is for this article about overcoming the weight plates sold out 😃, this script can obviously be adapted to over website and products.

This code is also available on Github.