headless-driver
Lightweight Python package to manage Selenium WebDriver in headless mode with proxy support, stealth tweaks, auto-driver installation, multi-driver management, download handling, and advanced search-scraping utilities
Features
- Headless and non-headless Chrome management
- Temporary or persistent user-data directories (profiles)
- HTTP and SOCKS proxy support
- Optional stealth mode (integrates with selenium-stealth when available)
- Automatic ChromeDriver install (via webdriver-manager) as an optional dependency
- Download folder management and automatic cleanup
- Screenshot and PDF export via Chrome DevTools
- Multi-driver manager to run many isolated browser instances
- Advanced search scraper with title, snippet, favicon, cached link, and batch search/export support
- DuckDuckGo's no-JavaScript endpoint by default, with automatic fallback to Bing, Mojeek, Startpage, Google and Yandex when an engine blocks the request
- Bounded page-load timeouts, so a stalled engine fails over instead of hanging
Installation
pip install headless-driver
Usage
from headless import Headless
hl = Headless()
driver = hl.get_driver()
driver.get("https://example.com")
print(driver.title)
hl.quit()
Or use as a context manager:
from headless import Headless
with Headless() as driver:
driver.get("https://example.com")
print(driver.title)
Search
from headless import SearchScraper
with SearchScraper(max_results=5) as scraper:
results = scraper.search("Nuhman PK github")
print(results) # [{"url": ..., "snippet": ...}, ...]
print(scraper.last_engine) # which engine actually answered
Searching starts at DuckDuckGo's no-JavaScript endpoint
(html.duckduckgo.com), which returns server-rendered HTML and so is markedly
faster than the JavaScript front end. If an engine serves a bot check, returns
nothing, or stalls, the next one in the chain is tried automatically:
duckduckgo -> duckduckgo_lite -> bing -> mojeek
-> duckduckgo_js -> startpage -> google -> yandex
search() returns [] only once every engine has been tried.
Stealth
from headless import ExtendedHeadless
hl = ExtendedHeadless(stealth=True)
driver = hl.get_driver()
driver.get("https://example.com")
print(driver.title)
hl.quit()
Proxy
from headless import ExtendedHeadless
hl = ExtendedHeadless(proxy="socks5://127.0.0.1:9050")
driver = hl.get_driver()
driver.get("https://example.com")
print(driver.title)
hl.quit()
Take Screen / Export PDF
from headless import ExtendedHeadless
hl = ExtendedHeadless(download_dir="/tmp/hd_downloads")
d = hl.get_driver()
d.get("https://example.com")
hl.screenshot("/tmp/example.png")
hl.save_pdf("/tmp/example.pdf")
hl.quit()
Auto Install Driver
from headless import ExtendedHeadless
hl = ExtendedHeadless(auto_install=True)
d = hl.get_driver()
d.get("https://example.com")
hl.screenshot("/tmp/example.png")
hl.save_pdf("/tmp/example.pdf")
hl.quit()
Multi driver manager
from headless import MultiDriverManager
mgr = MultiDriverManager()
a = mgr.create("bot1", stealth=True, auto_install=True)
b = mgr.create("bot2", proxy="http://1.2.3.4:3128", download_dir="/tmp/d2", auto_install=True)
da = a.get_driver()
db = b.get_driver()
mgr.quit_all()
Advanced scraper
from headless import AdvancedSearchScraper
scr = AdvancedSearchScraper(headless_options={"headless": True}, max_results=5)
res = scr.search("python headless")
print(scr.last_engine) # engine that produced `res`
batch = scr.search_batch(["python headless", "selenium stealth"], max_workers=2)
scr.export("results.json") # .json and .csv are supported
scr.quit()
Each result is a dict of url, title, snippet, favicon, cached,
quick_answer and engine. Click-tracking redirects (DuckDuckGo /l/?uddg=,
Bing /ck/a, Google /url?q=) are resolved to the real destination.
Choosing engines
# Start somewhere else; the rest of the chain still applies.
AdvancedSearchScraper(search_engine="bing")
# One engine only, no fallback.
AdvancedSearchScraper(fallback=False)
scr.search("python headless", engine="bing")
# Your own order.
AdvancedSearchScraper(search_engine="duckduckgo", fallback_engines=["bing", "mojeek"])
Available engines: duckduckgo (default), duckduckgo_lite, duckduckgo_js,
bing, mojeek, google, startpage, yandex. Add your own with
register_engine(name, spec).
Timeouts
AdvancedSearchScraper(page_load_timeout=20.0, wait_timeout=8.0)
page_load_timeout bounds how long one engine may take to load, and
wait_timeout how long to wait for its results to appear. Selenium's own
default is 300 seconds, so both are set well below it to keep a wedged engine
from stalling the whole search. Headless(page_load_timeout=30.0) applies the
same bound to any driver it hands out.
Search engines defend aggressively against automation, and Google in particular
serves a CAPTCHA to headless browsers on most networks. That is why the fallback
chain exists; blocks are reported when verbose=True.
API Documentation
Headless class
Headless(
user_data_dir: Optional[str] = None,
window_size: Tuple[int, int] = (1920, 1080),
user_agent: Optional[str] = None,
headless: bool = True,
chrome_driver_path: Optional[str] = None,
additional_args: Optional[List[str]] = None,
remote_url: Optional[str] = None,
verbose: bool = False,
page_load_timeout: Optional[float] = 30.0,
)
user_data_dir: Path for Chrome user data (temporary if not provided)window_size: Browser window size (default: 1920x1080)user_agent: Custom user agent stringheadless: Run Chrome in headless mode (default: True)chrome_driver_path: Path to chromedriver executable. When omitted, one is auto-detected on PATH and common install locations; if that driver turns out to mismatch the installed Chrome, a matching one is downloaded automaticallyadditional_args: List of extra Chrome argumentsremote_url: Use remote Selenium server if providedverbose: Print driver setup and teardown diagnosticspage_load_timeout: Seconds a page load may take before it is aborted (Nonedisables)
Methods
get_driver(): Returns a Selenium WebDriver instancequit(): Quits the driver and cleans up user data
Install Driver on Linux
sudo apt update
sudo apt install -y chromium chromium-driver
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file headless_driver-0.2.1.tar.gz.
File metadata
- Download URL: headless_driver-0.2.1.tar.gz
- Upload date:
- Size: 22.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd712fb732c876465acda5a2be95a94009aba9a56ed50423b4f516c641de3768
|
|
| MD5 |
c92bc07f8ebfa63dfb59caeb660724ba
|
|
| BLAKE2b-256 |
65131df2d8ae29b71041b82f6f61ba4fc684359232e24b86dc77b572b91bda23
|
File details
Details for the file headless_driver-0.2.1-py3-none-any.whl.
File metadata
- Download URL: headless_driver-0.2.1-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8a5d6171369a49def7d07937e2312154d093b0012a21c6c80ea2a9b9061f79b2
|
|
| MD5 |
1b46791eb5416d32830d585915aa2ea5
|
|
| BLAKE2b-256 |
5123197c73afaef0f73241f1bcf8e340bf31f0e1d5ee766d42948da5db48accb
|