139 lines
4.7 KiB
Python
139 lines
4.7 KiB
Python
from selenium import webdriver
|
|
from selenium.webdriver.chrome.service import Service
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
import time
|
|
from get_message import generate_custom_message
|
|
import logging
|
|
import random
|
|
from logging.handlers import RotatingFileHandler
|
|
import os
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
# Constants for login
|
|
USERNAME = os.getenv("USERNAME")
|
|
PASSWORD = os.getenv("PASSWORD")
|
|
|
|
# Set up logging
|
|
|
|
# Set up rotating log handler
|
|
handler = RotatingFileHandler('./wyzant_logs.log', maxBytes=5000000, backupCount=5) # 5 MB per log file, keeps 5 backups
|
|
logging.basicConfig(
|
|
handlers=[handler],
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(levelname)s - %(message)s'
|
|
)
|
|
|
|
logging.info("Starting script...")
|
|
|
|
REFRESH_WAIT_TIME = 120
|
|
REFRESH_VARIANCE = 15
|
|
|
|
# Selenium Config
|
|
chrome_driver_path = "/usr/local/bin/chromedriver/chromedriver"
|
|
service = Service(executable_path=chrome_driver_path)
|
|
driver = webdriver.Chrome(service=service)
|
|
|
|
# Go to login site
|
|
logging.info("Navigating to login page...")
|
|
driver.get("https://www.wyzant.com/login")
|
|
|
|
# Login
|
|
time.sleep(3)
|
|
username_input = WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.XPATH, "//form[@class='sso-login-form']//input[@id='Username']"))
|
|
)
|
|
username_input.send_keys(USERNAME)
|
|
password_input = WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.XPATH, "//form[@class='sso-login-form']//input[@id='Password']"))
|
|
)
|
|
password_input.send_keys(PASSWORD)
|
|
logging.info("Entered username and password...")
|
|
|
|
|
|
login_button = WebDriverWait(driver, 10).until(
|
|
EC.element_to_be_clickable((By.XPATH, "//form[@class='sso-login-form']//button[@type='submit']"))
|
|
)
|
|
login_button.click()
|
|
logging.info("Clicked login button.")
|
|
|
|
# Wait and click jobs link
|
|
time.sleep(3)
|
|
WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.XPATH, "//div[@class='profile-image round-photo']"))
|
|
)
|
|
job_count_element = WebDriverWait(driver, 10).until(
|
|
EC.element_to_be_clickable((By.XPATH, "//div[@data-templateid='jobCountTemplate']"))
|
|
)
|
|
job_count_element.click()
|
|
logging.info("Clicked jobs list link button.")
|
|
|
|
# Loop over the jobs list until no more jobs are found
|
|
while True:
|
|
try:
|
|
# Wait for the jobs list to load and locate the first job link
|
|
time.sleep(2)
|
|
|
|
first_job_description = WebDriverWait(driver, 10).until(
|
|
EC.element_to_be_clickable((By.CSS_SELECTOR, "#jobs-list .job-description"))
|
|
)
|
|
|
|
first_job_link = WebDriverWait(driver, 10).until(
|
|
EC.element_to_be_clickable((By.CSS_SELECTOR, "#jobs-list .row.spc-small-ew .job-details-link"))
|
|
)
|
|
|
|
first_student = WebDriverWait(driver, 10).until(
|
|
EC.element_to_be_clickable((By.CSS_SELECTOR, "#jobs-list .text-semibold.spc-zero-n.spc-tiny-s"))
|
|
)
|
|
|
|
# Extract job info for GPT
|
|
job_description_text = first_job_description.text
|
|
job_subject_text = first_job_link.text
|
|
job_student_text = first_student.text
|
|
|
|
# Generate and send message
|
|
message = generate_custom_message(job_description_text, job_student_text, job_subject_text)
|
|
logging.info(f"Generated custom message for {job_student_text}, subject: {job_subject_text}.")
|
|
|
|
first_job_link.click()
|
|
|
|
# Wait for the message text area and send the message
|
|
time.sleep(3)
|
|
text_area = WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.ID, "personal_message"))
|
|
)
|
|
text_area.clear() # Clears the text area if there's any existing text
|
|
text_area.send_keys(message) # Insert your message
|
|
|
|
# Check if the hourly rate checkbox exists and click it if present
|
|
try:
|
|
checkbox = WebDriverWait(driver, 2).until(
|
|
EC.presence_of_element_located((By.ID, "agree_partner_hourly_rate"))
|
|
)
|
|
checkbox.click()
|
|
logging.info("Clicked rate agreement checkbox.")
|
|
except:
|
|
logging.info("No rate agreement checkbox found.")
|
|
|
|
# Submit the application
|
|
submit_button = WebDriverWait(driver, 10).until(
|
|
EC.element_to_be_clickable((By.CSS_SELECTOR, "input.btn.old-button-color"))
|
|
)
|
|
submit_button.click()
|
|
logging.info("Application submitted successfully.")
|
|
|
|
# Wait for the page to redirect to the jobs list again
|
|
time.sleep(3)
|
|
|
|
except Exception as e:
|
|
logging.error(f"Failed find a job to apply. Waiting 1 mins")
|
|
delay = random.uniform(REFRESH_WAIT_TIME - REFRESH_VARIANCE, REFRESH_WAIT_TIME + REFRESH_VARIANCE)
|
|
time.sleep(60)
|
|
driver.refresh()
|
|
time.sleep(10)
|
|
|
|
|