auto_wyzant/main.py

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)