File size: 2,897 Bytes
fa8ff66 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | """
_driver.py β Shared Selenium Chrome driver factory.
All scrapers import _create_driver() from here so that Docker env-vars
(CHROME_BIN, CHROMEDRIVER_PATH) are respected in one place.
"""
from __future__ import annotations
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
def _create_driver(mobile: bool = False) -> webdriver.Chrome:
"""
Return a headless Chrome/Chromium instance tuned for Docker.
Picks up:
CHROME_BIN β path to chromium binary (default: /usr/bin/chromium)
CHROMEDRIVER_PATH β path to chromedriver (default: /usr/bin/chromedriver)
"""
chrome_bin = os.environ.get("CHROME_BIN", "/usr/bin/chromium")
driver_bin = os.environ.get("CHROMEDRIVER_PATH", "/usr/bin/chromedriver")
options = webdriver.ChromeOptions()
options.binary_location = chrome_bin
# ββ Headless & sandbox flags ββββββββββββββββββββββββββββββββββββββββββββββ
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-infobars")
options.add_argument("--disable-notifications")
options.add_argument("--disable-popup-blocking")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("--ignore-certificate-errors")
options.add_argument("--window-size=1920,1080")
options.add_argument("--remote-debugging-port=0") # avoid port conflicts
# ββ User-Agent ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
if mobile:
options.add_argument(
"--user-agent=Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) "
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1"
)
else:
options.add_argument(
"--user-agent=Mozilla/5.0 (X11; Linux x86_64) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
)
options.add_experimental_option("excludeSwitches", ["enable-automation", "enable-logging"])
options.add_experimental_option("useAutomationExtension", False)
service = Service(executable_path=driver_bin)
driver = webdriver.Chrome(service=service, options=options)
# Hide webdriver fingerprint
driver.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument",
{"source": "Object.defineProperty(navigator,'webdriver',{get:()=>undefined})"},
)
return driver
|