Fun With Python #3: Hacking Instagram Giveaways

Orestis Zekai
The Startup
Published in
7 min readJan 16, 2021

Welcome to “Fun with Python”, part 3. In this part, we will utilize Python and the selenium module to give ourselves greater odds of winning a giveaway.

Theory and Foundations

I assume everyone knows what a giveaway is. Even if you don’t, I am sure you have seen posts with descriptions like:

  1. Follow @some_name
  2. Follow @brand_name
  3. Tag 3 friends

Usually, it is done either by a relatively new IG account that wants to get some followers or by an already established big account in collaboration with a brand in order to promote the brand. In the latter case the influencer is also paid an amount by the brand owner. When the day comes, a lucky individual will be randomly picked from the comments and will win the gift.

But enough with “giveaway” theory. There are many contests where the price is an expensive mobile phone or even a car. Let’s see how Python can help getting our hands on them.

A first solution to this problem would be instapy. According to the definition in their github page, it is a:

Tooling that automates your social media interactions to “farm” Likes, Comments, and Followers on Instagram Implemented in Python using the Selenium module.

It is an easy to use, fast to code with library, that I have used in the past, leaving me very satisfied. The thing is that, when I tried it in this case, something was not working for me and the browser would stop in the “Accept Cookies” page.

This left me heartbroken. There were other that reported the same issue as me and they proposed some workarounds but none worked for my case.

I was stuck. I was facing a wall and I needed to figure a way to either jump over or break through it.

While I was looking desperately at the documentation trying to find a fix for my case, it hit me.

Implemented in Python using the Selenium module

Instapy is build using selenium. Selenium is a tool that is used to automate the testing of web applications. It is composed of several components, one of which is Selenium WebDriver.

Selenium WebDriver accepts commands and sends them to a browser. Using it, you can navigate to pages, click on buttons and boxes, fill in data, select from drop-downs and many more.

Finally, I see light. I will use selenium to build my own, custom solution.

Implementation

As stated before, Selenium WebDriver send commands to a browser. In our case, we will use Firefox. In order to drive theFirefox browser, you need to have geckodriver. Following this page, you can install the appropriate geckodriver version depending on your operating system. After you install geckodriver, setup you virtual environment and install selenium we are ready to start coding!

First, we need to initialize the Firefox driver. The browser language, by default will be your preferred language. If the language is not English, we have to set it. Also, there is an option to drive the browser headlessly, without actually seeing the browser itself. By default this option is disabled, but you may want to run it in a headless mode. You will understand why later.

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
# Set headless mode to False
options = Options()
options.headless = False
# Set the browser language
profile = webdriver.FirefoxProfile() profile.set_preference('intl.accept_languages', 'en-US, en')
# Initialize the driver
self.driver = webdriver.Firefox(options=options)

Great! Now that we have the browser ready, we need to navigate to instagram.

driver.get('https://instagram.com')

Again, the dreaded “Accept Cookies” button. This time I am going to click it though. In order to interact with an element in a browser using Selenium, you need to locate the element first. You can locate an element using many properties, but you need to find the one the fits best every case. For a detailed overview about locating elements you can refer here. In our case, we will use the xpath property and use the “Accept Cookies” text to locate the button. xpath can have weird syntax, but with a little practice you can master it. If such button exists, we will click it. Buttons offer us the click() method.

# Check if cookies accept popup appeared and click it        accept_button = driver.find_element_by_xpath(
"//button[contains(text(), 'Accept')]"
)
if accept_button:
accept_button.click()

Now, we should see the login form. Sometimes (due to internet connection issues, computer lagging and more) we need to wait until an element is loaded before we can interact with it. This is why Selenium offers WebDriverWait. You pass as arguments the driver and a timeout period in seconds and utilize the until method and define the expected condition at which the the waiting period is over.

In order to locate the xpath of the username field we will do the following steps:

  1. Open developer tools
  2. Click on the pointer icon on the top left
  3. Hover over the username input field and notice the html part that get highlighted on the right
  4. Right click > Copy > Copy XPath
Locate the username field xpath

After waiting for it to be loaded and locate it we will use the send_keys() method to fill in our username:

from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

WebDriverWait(driver, 20).until(
EC.presence_of_element_located((
By.XPATH,
'//*[@id="loginForm"]/div/div[1]/div/label/input'
))
).send_keys("my_cool_username")

After doing the same with the password field, we will locate and click the login button:

driver.find_element_by_xpath(
'//*[@id="loginForm"]/div/div[3]/button'
).click()

If you get prompted to save your login credentials you can either save them or not. You can locate the element you decide by using the xpath as previous. Be careful thought! If this page does not appear and you try to click any button that does not exist, the script will break and stop executing. To deal with this, we will add a try...except clause:

from selenium.common.exceptions import NoSuchElementException, TimeoutException
try:
WebDriverWait(driver,20).until(
EC.presence_of_element_located((
By.XPATH,
'/html/body/div[1]/section/main/div/div/div/div/button'
))
).click()
except NoSuchElementException:
pass
except TimeoutException:
pass

Now that we have accepted the cookies, logged in and saved our password (or not!) we are ready to start commenting! You need to navigate to the post you want to comment on using the driver.get() as we did before. Now you can locate the text field where you can write your comment and click on it. After that send the comment you want to send and then click at the “Post” button on the right. Notice the way we are using ActionChains to type the comment:

try:
WebDriverWait(self.driver, 20).until(
EC.presence_of_element_located((
By.XPATH,
'/html/body/div[1]/section/main/div/div[1]/article/div[3]/section[3]/div/form/textarea'))
).click()
actions = ActionChains(self.driver)
actions.send_keys("My comment will win this giveaway")
actions.perform()
self.driver.find_element_by_xpath(
"//button[contains(text(), 'Post')]"
).click()
except NoSuchElementException:
print('Element not found')
except TimeoutException:
print('Time out while waiting for the element to appear')

And this is it! We successfully posted our first comment using Python and Selenium WebDriver.

The last step is to put the part that gets the page of the giveaway post until the part that clicks the “Post” button in a loop. That way, we will add more comments to this post increasing the odds to win.

Conclusion

You saw how easy it was to implement the script and comment on posts, but here are some extras you can do and some considerations regarding this script.

  1. Executing this script on a server
    It goes without saying, but you can’t keep your computer running all day long just to have your script running. So, you can put it on a server. There are free options out there that can have your script executing even when you sleep at night. Be careful though! Most servers do not offer a GUI, hence you can run the browser in headless mode to avoid errors.
  2. Notify on exceptions
    In the try...except clauses we had above, we did nothing. In some cases we just pass and continue the code execution and in others we printed something meaningful. You can take that a step further and create a notification for you. You can send an email, a message on WhatsApp and many more.
  3. IG account blocked
    Yes, this is an option. Instagram may block your account from making comments. Not forever though. In most cases, you will be blocked for a couple of days and then you will be able to interact again. Instagram has many spam filters (i.e. commenting constantly, comments consisting only from emojis or tags etc) and there are thresholds as to how many comments an account can make per day/hour. For obvious reasons, Instagram keeps changing this policy and is not available to the public. But you can start small and experiment.
  4. A game of chance
    Even if you manage to make 1 million comments from your account, your brother’s account or your dog’s account, you may end up losing. The winner gets picked at random and in a game when luck is involved you can always lose. Our script just tries to make our odds bigger.
  5. Have I won anything?
    Yes! I have not tested this script a lot, but I won 2 contests. Neither of them was a shiny car though.

This concludes this article. I hope you enjoyed reading it and try it yourself. Let me know your thoughts and your ideas about it! In the meanwhile, you can find the rest of the “Fun with Python” series here.

--

--