Skip to content

Commit

Permalink
Automating job application on linkedin - bot
Browse files Browse the repository at this point in the history
  • Loading branch information
artur.sniegowski committed Sep 6, 2022
0 parents commit b420a42
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 0 deletions.
53 changes: 53 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.vi
*~
*.sass-cache
node_modules/
.tmp/

# OS or Editor folders
.DS_Store
Thumbs.db
.cache
.project
.settings
.tmproj
*.esproj
nbproject
*.sublime-project
*.sublime-workspace
*.komodoproject
.komodotools
_notes
dwsync.xml

# Environmental variables
.env

# Virtual enviroment
ENV/

### Django ###
*.sqlite3

#passwords
passwords.txt

# spotipy lib
token.txt
.cache
2 changes: 2 additions & 0 deletions Automating_job_applications_on_linkedin/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MY_LINKEDIN_EMAIL = "YOUR.EMAIL@gmail.com"
MY_LINKEDIN_PASSWORD = "Your_password"
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---------ChromeDriver 104.0.5112.79 (2022-08-03)---------
Supports Chrome version 104
52 changes: 52 additions & 0 deletions Automating_job_applications_on_linkedin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Automating_job_applications_on_linkedin

This is an automated job application bot. The program will use selenium WebDriver
to automate applying for jobs on LinkedIn with the "Easy Apply" function to send applications to all the jobs that meet your criteria (instead of just a single listing).
In the first step, it will log in to your LinkedIn account, and then go to the specific search job URL defined in the program by the user.
After accessing this URL, the bot will go through each of the application and asses if there is a function of Easy Apply.
If it doesn't exist, the job application will be skipped, and the bot will move to the next job application.
After finding the Easy Apply button, the bot will submit the first step of application by pressing it.
In the next step, the bot will validate how the application form looks.
If the application form will have the button next which indicates a multistep application, the bot will terminate the application,
only application with "submit application" will be accepted.
The bot will submit the application, and fill in the given phone number and send out the application.
After that, the bot will move to the next job application.  



Necessary steps to make the program work:</br>
1. Install Chrome browser https://www.google.com/intl/en_uk/chrome/ </br>
2. Download chrome driver (don't forget to match the version of your chrome with the version of the chrome driver) https://chromedriver.storage.googleapis.com/index.html?path=104.0.5112.79/, and unzip the file for your OS.
Mark the DIR to the chromedriver.exe file and adjust the *chrome_driver_path* in main.py. </br>
3. Sign up to LinkedIn  https://www.linkedin.com/ and configure your Profile. </br>
Make sure you've signed up to LinkedIn and save your email and password somewhere for later use.</br>
Upload your resume by going to Me -> Settings & Privacy -> Data Privacy -> Job Seeking Preferences -> Job Application Settings.</br>
NOTE: Do not enable 2-factor authentication/phone number verification while we are using Selenium.</br>
4. After creating the LinkedIn account, we have to change the name of .env.example to .env and define the environmental variables according to our account:</br>
MY_LINKEDIN_EMAIL = "YOUR.EMAIL@gmail.com"</br>
MY_LINKEDIN_PASSWORD = "Your_password"</br>
5. The user has to adjust the starting variables in the main.py:</br>
*PHONE_NUMBER* - phone number to be filled in the form during application.</br>
*WEBSITE_URL_FOR_THE_DRIVER* - URL for job search.</br>


---

Example of view Easy Apply application:</br>
![Screenshot](docs/img/01_easy_apply.png)</br>


Example of view of submitting application:</br>
![Screenshot](docs/img/02_submiting_applicatio.png)</br>


Example of view of invalid form with next button - multistep application is not supported:</br>
![Screenshot](docs/img/03_inalid_form_next.png)</br>

---


**The program was developed using python 3.10.6, selenium**


In order to run the program, you have to execute main.py.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 125 additions & 0 deletions Automating_job_applications_on_linkedin/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

# env variables !
from dotenv import load_dotenv
load_dotenv()
import os

################################################################################
## sensitive data ###
#####################
# user defined email and app password for your linkedin account !
# env variables ! - dont change here !
MY_LINKEDIN_EMAIL = os.environ.get('MY_LINKEDIN_EMAIL')
MY_LINKEDIN_PASSWORD = os.environ.get('MY_LINKEDIN_PASSWORD')
PHONE_NUMBER = "555555555" # user defined number
################################################################################


####################### SELENIUM SETTINGS #########################
# adjust this path to wherever you have unpacked the chrome driver file !
# dont forget that the verion of chrom drive has to match the verison of chrome browser
# https://chromedriver.chromium.org/downloads
# relative path you can use as well absolute path !
chrome_driver_path = "ChromeDriver/chromedriver.exe"

# creating the webdriver
driver = webdriver.Chrome(executable_path=chrome_driver_path)
# website url for the linkin job search with eaasy to apply status
# exampel url for web developer search
WEBSITE_URL_FOR_THE_DRIVER = "https://www.linkedin.com/jobs/search/?f_LF=f_AL&geoId=102257491&keywords=web%20developer&location=London%2C%20England%2C%20United%20Kingdom&redirect=false&position=1&pageNum=0"
# load the page at the given URL
driver.get(WEBSITE_URL_FOR_THE_DRIVER)
#######################################################################

# wait for the page to load
time.sleep(2)

###### login in to linked in account - after accesing the website #####
login_button_element = driver.find_element(By.XPATH,'/html/body/div[3]/header/nav/div/a[2]')
login_button_element.click()

# wait for the page to load
time.sleep(5)

################### log in pag - login with the user credentials ############
login_email_input_element = driver.find_element(By.NAME, 'session_key')
login_email_input_element.send_keys(MY_LINKEDIN_EMAIL)

login_password_input_element = driver.find_element(By.NAME, 'session_password')
login_password_input_element.send_keys(MY_LINKEDIN_PASSWORD)
login_password_input_element.send_keys(Keys.ENTER)

# wait for the page to load
time.sleep(5)

# getting all the jobs from the one page
# jobs_list_elements = driver.find_elements(By.CSS_SELECTOR,'.job-card-container--clickable')
jobs_list_elements = driver.find_elements(By.CSS_SELECTOR,'div.job-card-container--clickable')

print(len(jobs_list_elements))
# selecting job by job card
for job_element in jobs_list_elements:
# selectic the job card
job_element.click()

# wait for the page to load
time.sleep(1)

try:
# hit the easy apply button
easy_apply_button_element = driver.find_element(By.CSS_SELECTOR, 'div.jobs-apply-button--top-card button')
easy_apply_button_element.click()

# wait for the page to load
time.sleep(2)

# input phone number and continue
phone_input_element = driver.find_element(By.CLASS_NAME,'fb-single-line-text__input')
if phone_input_element.text == "": # if empty write down the phone number
phone_input_element.send_keys(PHONE_NUMBER)

# getting the submit button
submit_button_element = driver.find_element(By.CSS_SELECTOR,'footer button')

# checking if this is the right button
# we are discarding multi step applications
# only submit will be accepted
if submit_button_element.get_attribute('aria-label') == 'Submit application':
# submitting our application
submit_button_element.click()

# wait for the page to load
time.sleep(3)

# close the confirmation of submiting application
close_application_element = driver.find_element(By.CLASS_NAME,'artdeco-modal__dismiss')
close_application_element.click()

# wait for the page to load
time.sleep(2)

else:
# if the button is next we will close the appliction
close_application_element = driver.find_element(By.CLASS_NAME,'artdeco-modal__dismiss')
close_application_element.click()
# wait for the page to load
time.sleep(2)

# pressing the discard button
discard_application_element = driver.find_element(By.CLASS_NAME,'artdeco-modal__confirm-dialog-btn')
discard_application_element.click()
# wait for the page to load
time.sleep(2)

except NoSuchElementException:
print("No application button, skipped.")
continue

print("done")
# close the browser
driver.quit() # this will close the whole browser
Binary file not shown.
1 change: 1 addition & 0 deletions Automating_job_applications_on_linkedin/runtime.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Python 3.10.6

0 comments on commit b420a42

Please sign in to comment.