Automate LinkedIn Connection Request using Python and Excel database

Bobby Doshi
5 min readAug 12, 2022

--

Redundant image to serve as article’s preview image for SEO purposes

What is LinkedIn?

It is a social media for professionals to showcase their achievements, for some to network and find jobs, and for others to use it as Facebook.

Anyway, why are we here?

Automation arises from the need to be lazy. So, here is a short story.

Harry, my friend, posts on the WhatsApp group a google excel sheet in which all have to enter their LinkedIn profile URL so we can connect. Sounds great! It doesn’t matter if you know people, but “Gotta Catch ’Em All”.

I wake up in the morning and check the sheet and there are 246 entries. My actions looked as follows -

Click on Google Sheet tab > Click on Profile URL > Click “Connect” once the LinkedIn page loads > Close LinkedIn tab > Repeat.

Let’s automate it.

Scripting Requirements

  1. Python
  2. Selenium
  3. pandas
  4. geckodriver

Setting up environment

  1. Install Python from here
  2. Create a virtual environment “env” under the project directory “automate_linkedin”
python -m venv \base_path\automate_linkedin\env

3. Install Selenium and Pandas

pip install selenium
pip install pandas

4. Download geckodriver from here and extract it under the project directory

Crack your knuckles to Code

  1. Get the data from csv file and generate a list of LinkedIn profile URL
linkedin_database = pandas.read_csv("linkedin_database.csv")
profile_url_list = list(linkedin_database.iloc[0:, 2])

where our CSV is in the format

csv structure

2. Provide the path for geckodriver for the Firefox browser and start the session

service = Service('geckodriver-v0.31.0-win64\\geckodriver.exe')
browser = webdriver.Firefox(service=service)

3. Automate Login

  • Load the base login URL of LinkedIn
url = "https://www.linkedin.com/"
browser.get(url)
  • Inspect web page and find ID for HTML element for username text field and password text field
  • Get element by ID discovered above using selenium find_element method
username = browser.find_element(By.ID,"session_key")
password = browser.find_element(By.ID,"session_password")
  • Next, we are sending keys, this is similar to entering keys using your keyboard. For this we use selenium send_keys method
username.send_keys("<Enter your email id>")
password.send_keys("<Enter your password>")
  • Finally, inspect web page and find class_name for HTML element for submit button, get that element using class_name and click it using click method
browser.find_element(By.CLASS_NAME,"sign-in-form__submit-button").click()

4. Sending Connection Requests

  • Fetch each profile URL, check if it is a valid URL and then load the URL and wait for a few seconds till the web page is completely loaded
for profile_url in profile_url_list:
print(profile_url)
if not profile_url or pandas.isnull(profile_url):
print("Empty String\n")
continue
try:
browser.get(profile_url)
except InvalidArgumentException:
print("Bad profile URL\n")
continue
sleep(10)
  • Understanding different scenarios we may encounter while sending a connection request

# Scenario 1: “Connect” button is on screen itself

“Connect” button is visible on screen

# Scenario 2: “Connect” button is under “More” dropdown

“Connect” action under “More” dropdown

# Scenario 3: You are already connected with that user or you had previously sent a request which is in “Pending” mode

Hence, we have to handle Scenarios 1 and 2 and ignore any instances of 3rd.

  • Finding the XPath to the “Connect button”. More on XPath can be found here.

# Scenario 1: For this, we only need to find XPath to “Connect” button on the screen, get element by XPath and then click on it

def check_exists_by_xpath(browser,xpath):
try:
browser.find_element(By.XPATH,xpath)
except NoSuchElementException:
return False
return True
xpath="//main[@id='main']/section[1]/div[2]/div[3]/div[1]/button[1]/span[contains(.,'Connect')]"
connect_xpath="//main[@id='main']/section[1]/div[2]/div[3]/div[1]/button[1]"

if check_exists_by_xpath(browser,xpath):
browser.find_element(By.XPATH,connect_xpath).click()
check_popup(browser)
print("Connected\n")

# Scenario 2: Here we first have to find XPath to “More” dropdown > get that element > click on it > find Xpath to “Connect” button under it > get that element > click on it

more_xpath="//main[@id='main']/section[1]/div[2]/div[3]/div[1]//button[contains(@aria-label, 'More actions')]"
more_connect_xpath="//main[@id='main']/section[1]/div[2]/div[3]/div[1]//button[contains(@aria-label, 'More actions')]/parent::node()/div/div/ul//div/span[text()='Connect']"
if check_exists_by_xpath(browser, more_xpath):
browser.find_element(By.XPATH,more_xpath).click()
if check_exists_by_xpath(browser, more_connect_xpath):
browser.find_element(By.XPATH,more_connect_xpath).click()
check_popup(browser)
print("Connected\n")
else:
print("No connection option under More button\n")
  • Handling the different pop-ups post clicking “Connect”

Let’s discover the different pop-ups we get on clicking “Connect”

#Pop-up 1:

“Customize Invitation” pop-up
def check_exists(element,browser,sel):
try:
browser.find_element(element,sel)
except NoSuchElementException:
return False
return True
if check_exists(By.CSS_SELECTOR,browser,'[aria-label="Send now"]'):
browser.find_element(By.CSS_SELECTOR,'[aria-label="Send now"]').click

In the above code snippet, we are trying to find an identifier for “Send” button which here is CSS_SELECTOR ‘[aria-label=”Send now”]’ for that element and then clicking on it.

#Pop-up 2:

“How do you know” pop-up
if check_exists(By.CSS_SELECTOR,browser,'[aria-label="Other"]'):
browser.find_element(By.CSS_SELECTOR,'[aria-label="Other"]').click()
browser.find_element(By.CSS_SELECTOR,'[aria-label="Connect"]').click()

In the above code snippet, we are trying to find an identifier for “Other” button which here is CSS_SELECTOR ‘[aria-label=”Other”]’ and then for “Connect” which is CSS_SELECTOR ‘[aria-label=”Connect”]’. “Connect” will only get activated once “Other” or any one of the options is selected.

#Pup-up 3:

“Prefers to be followed” pop-up
if check_exists(By.CSS_SELECTOR,browser,'[aria-label="Connect"]'):
browser.find_element(By.CSS_SELECTOR,'[aria-label="Connect"]').click()

In the above code snippet, we are trying to find an identifier for “Connect” which is CSS_SELECTOR ‘[aria-label=”Connect”]’ and then clicking on it.

These pop-ups may come up one after the another and hence we create some kind of recursive method till all pop-ups are cleared.

def check_popup(browser):
if check_exists(By.CSS_SELECTOR,browser,'[aria-label="Send now"]'):
browser.find_element(By.CSS_SELECTOR,'[aria-label="Send now"]').click()
elif check_exists(By.CSS_SELECTOR,browser,'[aria-label="Other"]'):
browser.find_element(By.CSS_SELECTOR,'[aria-label="Other"]').click()
browser.find_element(By.CSS_SELECTOR,'[aria-label="Connect"]').click()
check_popup(browser)
elif check_exists(By.CSS_SELECTOR,browser,'[aria-label="Connect"]'):
browser.find_element(By.CSS_SELECTOR,'[aria-label="Connect"]').click()
check_popup(browser)
return

Now sit back and enjoy!!!

Note: This article serves as an educational tool on the use of selenium and does not encourage breaking of any LinkedIn rules and policies and as such should not be used in any form that harms anyone.

Complete code is available on my Github repo 👇

--

--

Bobby Doshi

Deconstruct existing biases and preconceived patterns in data analysis and decision-making processes.