Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chrome driver fix with upgrade to Selenium functions #17

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"password" : "your_password",
"keywords" : "your_keywords",
"location" : "your_location",
"driver_path" : "your_path_to_webdriver"
"optional_driver_path" : ""
}
53 changes: 33 additions & 20 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,20 @@ def __init__(self, data):
self.password = data['password']
self.keywords = data['keywords']
self.location = data['location']
self.driver = webdriver.Chrome(data['driver_path'])
try:
if data['optional_driver_path'] != '':
# user driver path is defined
self.driver = webdriver.Chrome(data['optional_driver_path'])
else:
# use new way of getting chrome webdriver user did not set driver path
options = webdriver.ChromeOptions()
self.driver = webdriver.Chrome(options=options)
except:
# Driver issue, ending program
print("Chrome driver issue. Try updating chrome to Version 116 or higher")
print('Ensure driver_path is set correctly in config.json or set driver_config to "" ')
print('Exiting...')
exit()

def login_linkedin(self):
"""This function logs into your personal LinkedIn profile"""
Expand All @@ -27,10 +40,10 @@ def login_linkedin(self):
self.driver.get("https://www.linkedin.com/login")

# introduce email and password and hit enter
login_email = self.driver.find_element_by_name('session_key')
login_email = self.driver.find_element(By.NAME, 'session_key')
login_email.clear()
login_email.send_keys(self.email)
login_pass = self.driver.find_element_by_name('session_password')
login_pass = self.driver.find_element(By.NAME, 'session_password')
login_pass.clear()
login_pass.send_keys(self.password)
login_pass.send_keys(Keys.RETURN)
Expand All @@ -39,14 +52,14 @@ def job_search(self):
"""This function goes to the 'Jobs' section a looks for all the jobs that matches the keywords and location"""

# go to Jobs
jobs_link = self.driver.find_element_by_link_text('Jobs')
jobs_link = self.driver.find_element(By.LINK_TEXT, 'Jobs')
jobs_link.click()

# search based on keywords and location and hit enter
search_keywords = self.driver.find_element_by_css_selector(".jobs-search-box__text-input[aria-label='Search jobs']")
search_keywords = self.driver.find_element(By.CSS_SELECTOR, ".jobs-search-box__text-input[aria-label='Search jobs']")
search_keywords.clear()
search_keywords.send_keys(self.keywords)
search_location = self.driver.find_element_by_css_selector(".jobs-search-box__text-input[aria-label='Search location']")
search_location = self.driver.find_element(By.CSS_SELECTOR, ".jobs-search-box__text-input[aria-label='Search location']")
search_location.clear()
search_location.send_keys(self.location)
search_location.send_keys(Keys.RETURN)
Expand All @@ -55,33 +68,33 @@ def filter(self):
"""This function filters all the job results by 'Easy Apply'"""

# select all filters, click on Easy Apply and apply the filter
all_filters_button = self.driver.find_element_by_xpath("//button[@data-control-name='all_filters']")
all_filters_button = self.driver.find_element(By.XPATH, "//button[@data-control-name='all_filters']")
all_filters_button.click()
time.sleep(1)
easy_apply_button = self.driver.find_element_by_xpath("//label[@for='f_LF-f_AL']")
easy_apply_button = self.driver.find_element(By.XPATH, "//label[@for='f_LF-f_AL']")
easy_apply_button.click()
time.sleep(1)
apply_filter_button = self.driver.find_element_by_xpath("//button[@data-control-name='all_filters_apply']")
apply_filter_button = self.driver.find_element(By.XPATH, "//button[@data-control-name='all_filters_apply']")
apply_filter_button.click()

def find_offers(self):
"""This function finds all the offers through all the pages result of the search and filter"""

# find the total amount of results (if the results are above 24-more than one page-, we will scroll trhough all available pages)
total_results = self.driver.find_element_by_class_name("display-flex.t-12.t-black--light.t-normal")
total_results = self.driver.find_element(By.CLASS_NAME, "display-flex.t-12.t-black--light.t-normal")
total_results_int = int(total_results.text.split(' ',1)[0].replace(",",""))
print(total_results_int)

time.sleep(2)
# get results for the first page
current_page = self.driver.current_url
results = self.driver.find_elements_by_class_name("occludable-update.artdeco-list__item--offset-4.artdeco-list__item.p0.ember-view")
results = self.driver.find_elements(By.CLASS_NAME, "occludable-update.artdeco-list__item--offset-4.artdeco-list__item.p0.ember-view")

# for each job add, submits application if no questions asked
for result in results:
hover = ActionChains(self.driver).move_to_element(result)
hover.perform()
titles = result.find_elements_by_class_name('job-card-search__title.artdeco-entity-lockup__title.ember-view')
titles = result.find_elements(By.CLASS_NAME, 'job-card-search__title.artdeco-entity-lockup__title.ember-view')
for title in titles:
self.submit_apply(title)

Expand All @@ -90,10 +103,10 @@ def find_offers(self):
time.sleep(2)

# find the last page and construct url of each page based on the total amount of pages
find_pages = self.driver.find_elements_by_class_name("artdeco-pagination__indicator.artdeco-pagination__indicator--number")
find_pages = self.driver.find_elements(By.CLASS_NAME, "artdeco-pagination__indicator.artdeco-pagination__indicator--number")
total_pages = find_pages[len(find_pages)-1].text
total_pages_int = int(re.sub(r"[^\d.]", "", total_pages))
get_last_page = self.driver.find_element_by_xpath("//button[@aria-label='Page "+str(total_pages_int)+"']")
get_last_page = self.driver.find_element(By.XPATH, "//button[@aria-label='Page "+str(total_pages_int)+"']")
get_last_page.send_keys(Keys.RETURN)
time.sleep(2)
last_page = self.driver.current_url
Expand All @@ -103,11 +116,11 @@ def find_offers(self):
for page_number in range(25,total_jobs+25,25):
self.driver.get(current_page+'&start='+str(page_number))
time.sleep(2)
results_ext = self.driver.find_elements_by_class_name("occludable-update.artdeco-list__item--offset-4.artdeco-list__item.p0.ember-view")
results_ext = self.driver.find_elements(By.CLASS_NAME, "occludable-update.artdeco-list__item--offset-4.artdeco-list__item.p0.ember-view")
for result_ext in results_ext:
hover_ext = ActionChains(self.driver).move_to_element(result_ext)
hover_ext.perform()
titles_ext = result_ext.find_elements_by_class_name('job-card-search__title.artdeco-entity-lockup__title.ember-view')
titles_ext = result_ext.find_elements(By.CLASS_NAME, 'job-card-search__title.artdeco-entity-lockup__title.ember-view')
for title_ext in titles_ext:
self.submit_apply(title_ext)
else:
Expand All @@ -122,7 +135,7 @@ def submit_apply(self,job_add):

# click on the easy apply button, skip if already applied to the position
try:
in_apply = self.driver.find_element_by_xpath("//button[@data-control-name='jobdetails_topcard_inapply']")
in_apply = self.driver.find_element(By.XPATH, "//button[@data-control-name='jobdetails_topcard_inapply']")
in_apply.click()
except NoSuchElementException:
print('You already applied to this job, go to next...')
Expand All @@ -131,17 +144,17 @@ def submit_apply(self,job_add):

# try to submit if submit application is available...
try:
submit = self.driver.find_element_by_xpath("//button[@data-control-name='submit_unify']")
submit = self.driver.find_element(By.XPATH, "//button[@data-control-name='submit_unify']")
submit.send_keys(Keys.RETURN)

# ... if not available, discard application and go to next
except NoSuchElementException:
print('Not direct application, going to next...')
try:
discard = self.driver.find_element_by_xpath("//button[@data-test-modal-close-btn]")
discard = self.driver.find_element(By.XPATH, "//button[@data-test-modal-close-btn]")
discard.send_keys(Keys.RETURN)
time.sleep(1)
discard_confirm = self.driver.find_element_by_xpath("//button[@data-test-dialog-primary-btn]")
discard_confirm = self.driver.find_element(By.XPATH, "//button[@data-test-dialog-primary-btn]")
discard_confirm.send_keys(Keys.RETURN)
time.sleep(1)
except NoSuchElementException:
Expand Down