import os import threading from concurrent.futures import ThreadPoolExecutor, as_completed import gradio as gr from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait, Select from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException from selenium.webdriver.chrome.options import Options # Suppress unnecessary logs os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' os.environ['WDM_LOG'] = '0' # List of companies to search companies = [ {'url': 'https://www.distilleryvfx.com/careers', 'name': 'Distillery VFX', 'action': None}, {'url': 'https://barnstormvfx.bamboohr.com/careers', 'name': 'Barnstorm VFX', 'action': None}, {'url': 'https://careers.theembassyvfx.com/#jobs', 'name': 'The Embassy VFX', 'action': None}, {'url': 'https://www.cosavfx.com/opportunities/', 'name': 'Cosa VFX', 'action': None}, {'url': 'https://www.hydraulx.com/careers/', 'name': 'Hydraulx', 'action': None}, {'url': 'https://globalus242.dayforcehcm.com/CandidatePortal/en-US/craftyapes', 'name': 'Crafty Apes', 'action': None}, {'url': 'https://www.belofx.com/careers', 'name': 'BElofx', 'action': None}, {'url': 'https://image-engine.com/jobs/#jobs', 'name': 'Image Engine', 'action': None}, {'url': 'https://www.zoicstudios.com/join', 'name': 'Zoic Studios', 'action': None}, {'url': 'https://animallogic.com/careers/jobs/', 'name': 'Animal Logic', 'action': None}, {'url': 'https://cinesite.com/job-vacancies/?location=vancouver&division=!feature%20animation', 'name': 'Cinesite', 'action': None}, {'url': 'http://careers.digitaldomain.com/', 'name': 'Digital Domain', 'action': 'select_vancouver'}, {'url': 'https://www.company3.com/careers/', 'name': 'Company 3', 'action': None}, {'url': 'https://recruitment.phantom-fx.com/jobs/Careers', 'name': 'Phantom FX', 'action': None}, {'url': 'https://scanlinevfx.com/careers/', 'name': 'Scanline VFX', 'action': None}, {'url': 'https://www.pixomondo.com/careers', 'name': 'Pixomondo', 'action': None}, {'url': 'https://www.dneg.com/join-us/open-positions', 'name': 'DNEG', 'action': 'select_vancouver'}, {'url': 'https://jobs.disneycareers.com/search-jobs?orgIds=391-28648&ascf=[%7B%22key%22:%22custom_fields.IndustryCustomField%22,%22value%22:%22Industrial%20Light%20%26%20Magic%22%7D]', 'name': 'ILM', 'action': None}, {'url': 'https://www.imageworks.com/job-postings', 'name': 'Sony Pictures Imageworks', 'action': None} ] target_jobs = ['FX Artist', 'FX Technical Director', 'FX TD'] MAX_WORKERS = 4 # Number of parallel browsers # Force ChromeDriverManager to download a version compatible with Chromium 133. # Passing the version as a positional argument. driver_path = ChromeDriverManager("133.0.6943.41").install() def check_company(company, chrome_options): driver = webdriver.Chrome( service=Service(driver_path), options=chrome_options ) driver.implicitly_wait(5) try: url = company['url'] driver.get(url) # If a specific action is required (like selecting Vancouver), perform it. if company['action'] == 'select_vancouver': try: if 'digitaldomain' in url: dropdown = WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.ID, "current-openings-select")) ) Select(dropdown).select_by_visible_text("Vancouver") WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".job-listings")) ) elif 'dneg' in url: dropdown = WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, "select[data-test-id='select-location']")) ) Select(dropdown).select_by_visible_text("Vancouver") except TimeoutException: return None # Check if any of the target job titles appear in the page source. page_text = driver.page_source.lower() found = any(job.lower() in page_text for job in target_jobs) if found: return (company['name'], company['url']) except Exception: return None finally: driver.quit() return None def run_job_search(): chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") chrome_options.add_argument("--ignore-certificate-errors") chrome_options.add_argument("--log-level=3") chrome_options.add_experimental_option('excludeSwitches', ['enable-logging']) chrome_options.page_load_strategy = 'eager' # Set the binary location for Chromium. chrome_options.binary_location = "/usr/bin/chromium" results = [] with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor: futures = [] for company in companies: futures.append(executor.submit(check_company, company, chrome_options)) for future in as_completed(futures): result = future.result() if result: results.append(result) # Build an HTML output with clickable links. if results: html = "

Companies with open positions:

" else: html = "

No matching job listings found.

" return html # Define a simple Gradio interface. demo = gr.Interface( fn=run_job_search, inputs=[], outputs=gr.HTML(label="Job Search Results"), title="FX Artist/FX TD Vancouver Job Search", description="Click the button below to search for FX job openings across multiple companies, all located in Vancouver." ) if __name__ == "__main__": # To create a public link, set share=True. demo.launch(share=True)