How to Write Automated Birthday Posts on Facebook Using Selenium

Written by elon-not-musk | Published 2020/05/18
Tech Story Tags: selenium | web-scraping-with-python | life-hack | python-tutorials | python | automated-birthday-posts | facebook | hackernoon-top-story

TLDR How to Write Automated Birthday Posts on Facebook using Selenium Web Driver. This will save you hundreds of seconds during the week, and maybe even minutes during the course of the year. With a few lines of Python and easy use of Selenium, we can have you posting on friends' walls in no time. We need to locate the tab using 'inspect element' or F12 on Windows to find the tab. We can then write our message and send it to Facebook. As of May 2020, I figured out that the right-most tab consists of an Ad, Birthdays and Messenger, the tab, falls under a class of elements labelled 'Birthdays'via the TL;DR App

Are you the kind of person that always forgets their friends’  birthdays? Do you find yourself scrolling through Facebook, wincing at the realization that you didn’t post a congratulatory message yesterday on your bestie’s wall? And what use is that tiny ‘birthday’ tab that Facebook so helpfully sequesters in the top right corner of my Newsfeed. No big deal, right? Wrong. You might not have remembered their birthday, but they will definitely remember that you didn’t remember to remember it - and bye, bye, bestie. But don’t panic -  here lies the solution to your woes, and it's also pretty easy. 
In this tutorial, I will teach you how to simply set up an automatic birthday poster on friends' walls. My inspiration for this tutorial comes from a GeeksforGeeks post seen here, but with more updated selectors and a deeper dive into how to properly automate the process. This will save you hundreds of seconds during the week, and maybe even minutes during the course of the year! Nevertheless, with a few lines of Python and easy use of Selenium Web Driver, we can have you posting on friends' walls in no time.

Installation and Getting Started

Whenever starting a new project, I always create a new Anaconda environment to store all of my dependencies. This is helpful because it allows me to separate my projects and their dependencies in distinct places, which allows for easy deployment if need be, and clear package-managing. We can spin up a new environment in your CLI (I like Anaconda Powershell Prompt) like so:
conda create --name scraper python=3.5 
Easily install Selenium libraries for Python using pip. More info on installation can be found here.
pip install selenium
Next, we need to install a web driver (also called proxies) that Selenium will utilize in order to control the actual browser. They are often created by the browser vendors themselves. You can use any browser, but I personally prefer ChromeDriver for Google Chrome/Chromium. You can download the web driver here. It is also important to remember where you downloaded the web driver executable so we can tell our Python script where it is located. Mine was saved automatically to a folder in my Drivers directory, at 'C:\Drivers\Chrome_driver\chromedriver'.

Connecting to our Driver and Logging in

Create a new Python script. I've named mine 'birthday_writer.py'. We're going to need to do the following in order to complete our task:
  • Connect the driver and access our target website
  • Log in with credentials
  • Find the XPath selector of the 'Birthdays' tab
  • Write our message and send
In our import statement, we need the web driver library from Selenium, and the time library in order to set necessary delays to give the browser time to load.
from selenium import webdriver
import time
Next, we set up a driver object with the file destination of the ChromeDriver executable, and connect to Facebook.
CHROME_DRIVER_PATH = 'C:\Drivers\Chrome_driver\chromedriver'
driver = webdriver.Chrome(executable_path = CHROME_DRIVER_PATH)
driver.get("https://www.facebook.com")
By using "inspect element" or F12 on Windows, we can detect that the email text box element contains the id 'email'. The password's id is similar, with its id being 'pass'. We can utilize the 'find_element_by_id' function to locate those elements within the HTML. After obtaining the text box elements, we can call the 'send_keys(string)' method on those elements to fill in the boxes with a specified string. Here is the code for this step:
USERNAME = "username@gmail.com"
PASSWORD = "password1234"
user_name_box = driver.find_element_by_id("email")
user_name_box.send_keys(USERNAME)

password_box = driver.find_element_by_id("pass")
password_box.send_keys(PASSWORD)

login_box = driver.find_element_by_id('loginbutton') 
login_box.click()
print("login successful!!!")
time.sleep(3)
And we're in! That was easy!

Locating Birthdays Tab and Posting on Walls

Next, we need to locate the 'Birthdays' tab using 'inspect element' or F12 on Windows. This can be a bit tricky, and may vary browser to browser or user to user. As of May, 2020, I figured out that the right-most tab, which consists of an Ad, Birthdays, and the Messenger tab, falls under a class of elements labelled 'cxgpxx05 sj5x9vvc', probably encrypted by Facebook to prevent readability. The selector then obtains a list of several different elements with that class label, where the 2nd indexed element contains the 'Birthdays' button. We can subscript to it (right_buttons[1] obtains the second element), click the element, and wait for it to load:
right_buttons = driver.find_elements_by_xpath("//*[@class= 'cxgpxx05 sj5x9vvc']")
right_buttons[1].click()
time.sleep(1)
Lastly, we come to something that looks like this:
Now, we can write an XPath selector that enables us to capture all the text boxes so we can write our message. The selector in combination with the method 'find_elements_by_xpath('XPath')' will give us a list of our desired text boxes. We can then iterate through each text box, let's call them 'els', use the 'send_keys(string)' command along with our desired message, and press the 'RETURN' key.
birthday_boxes = driver.find_elements_by_xpath("//*[contains(@aria-label, 'Birthdays')]//*[@class='_1mf _1mj']")
count = 0
for els in birthday_boxes:
    try:
        count +=1
        els.send_keys("Happy birthday!")
        els.send_keys(Keys.RETURN) 
        print("Birthday Wish posted for friend" + str(count)) 
    except:
        print("couldn't post")

print("done")
time.sleep(2)
driver.close()
And that's it! That was so fricken easy! Next, to top it all off, we can also automate our script by running it at a certain time every day.

Automating the Script

If you want to automate the task, we need to do the following:
  1. Create a Windows Batch file that calls our Python script and runs it
  2. Set up Windows Task Scheduler to call the executable file at a specified time each day
You can write something similar to I have written below in a batch file cleverly named 'birthday_task.bat'. If you're using an Anaconda environment like I am, you first need to call Anaconda's 'activate.bat' batch file where it is stored locally on your computer in order to officially run the Anaconda shell. This is usually found in a directory similar to 'C:\Users\myname\Anaconda3\Scripts\activate.bat'. Then, you can activate your environment where your dependencies lie (mine is called 'scraper') and then call your python script.
call C:\Users\...\Anaconda3\Scripts\activate.bat
call activate scraper
python C:\...\...\Desktop\birthday_writer.py
conda deactivate
Lastly, with the batch file's location kept in mind, we can create a task on Windows Task Scheduler very easily using the following tutorial. Setting it up should only take a couple of minutes. And we're done! Now you can be the best friend you've always dreamed of being :) If you want to see the full code, it can be found at this Github repository.

Published by HackerNoon on 2020/05/18