feat: Some quality of life improvements
This commit is contained in:
86
proxy/selenium_utils.py
Normal file
86
proxy/selenium_utils.py
Normal file
@@ -0,0 +1,86 @@
|
||||
import logging
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
||||
from config import HEADLESS, CF_WAIT_TIME, SELENIUM_URL, TARGET_URL
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_chrome_options() -> Options:
|
||||
options = Options()
|
||||
if HEADLESS:
|
||||
options.add_argument("--headless=new")
|
||||
options.add_argument("--no-sandbox")
|
||||
options.add_argument("--disable-dev-shm-usage")
|
||||
options.add_argument("--disable-gpu")
|
||||
options.add_argument("--disable-software-rasterizer")
|
||||
options.add_argument("--disable-extensions")
|
||||
options.add_argument("--disable-blink-features=AutomationControlled")
|
||||
options.add_argument("--disable-setuid-sandbox")
|
||||
options.add_argument("--disable-background-networking")
|
||||
options.add_argument("--disable-default-apps")
|
||||
options.add_argument("--disable-sync")
|
||||
options.add_argument("--disable-translate")
|
||||
options.add_argument("--metrics-recording-only")
|
||||
options.add_argument("--mute-audio")
|
||||
options.add_argument("--no-first-run")
|
||||
options.add_argument("--safebrowsing-disable-auto-update")
|
||||
options.add_argument("--ignore-certificate-errors")
|
||||
options.add_argument("--ignore-ssl-errors")
|
||||
options.add_argument("--user-data-dir=/tmp/chrome-data")
|
||||
options.add_argument("--disable-features=IsolateOrigins,site-per-process")
|
||||
return options
|
||||
|
||||
|
||||
def apply_stealth_scripts(driver: webdriver.Remote) -> None:
|
||||
driver.execute_script("""
|
||||
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
|
||||
Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3, 4, 5]});
|
||||
Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});
|
||||
window.chrome = {runtime: {}};
|
||||
|
||||
const originalQuery = window.navigator.permissions.query;
|
||||
window.navigator.permissions.query = (parameters) => (
|
||||
parameters.name === 'notifications'
|
||||
? Promise.resolve({state: Notification.permission})
|
||||
: originalQuery(parameters)
|
||||
);
|
||||
Object.defineProperty(navigator, 'permissions', {get: () => window.navigator.permissions});
|
||||
""")
|
||||
|
||||
|
||||
def fetch_fresh_credentials() -> tuple[str, str] | None:
|
||||
log.info("Starting Selenium to fetch fresh credentials...")
|
||||
|
||||
driver = None
|
||||
try:
|
||||
driver = webdriver.Remote(
|
||||
command_executor=f"{SELENIUM_URL}/wd/hub",
|
||||
options=get_chrome_options(),
|
||||
)
|
||||
apply_stealth_scripts(driver)
|
||||
driver.get(TARGET_URL)
|
||||
|
||||
wait = WebDriverWait(driver, CF_WAIT_TIME)
|
||||
wait.until(EC.presence_of_element_located((By.ID, "logo")))
|
||||
|
||||
user_agent = driver.execute_script("return navigator.userAgent;")
|
||||
selenium_cookies = driver.get_cookies()
|
||||
cookies = "; ".join(
|
||||
f"{c['name']}={c['value']}"
|
||||
for c in selenium_cookies
|
||||
)
|
||||
log.info("Successfully extracted credentials via Selenium")
|
||||
return (user_agent, cookies)
|
||||
|
||||
except Exception as e:
|
||||
log.error(f"Failed to extract credentials: {e}")
|
||||
return None
|
||||
|
||||
finally:
|
||||
if driver is not None:
|
||||
driver.quit()
|
||||
Reference in New Issue
Block a user