julia-browser
A headless web browser you can pip install. Pages run real JavaScript in Mozilla
SpiderMonkey against a full DOM, are laid out with Stylo + Taffy (the CSS engines from
Servo/Firefox), and can be screenshotted, read as markdown, or driven by clicks and typing.
The engine is written in Rust; this package is its Python binding (PyO3). No Chrome, no
Node, no driver process.
pip install julia-browser
Drive a page
from julia_browser import Browser
with Browser() as b:
b.open("https://news.ycombinator.com")
print(b.title)
b.click("text=new") # CSS selectors or text=...
print(b.read()[:800]) # readable markdown of the live page
stories = b.eval("[...document.querySelectorAll('.titleline > a')].map(a => a.textContent)")
b.screenshot(path="hn.png") # PNG of the viewport (full_page=True for all of it)
Forms:
with Browser() as b:
b.open("https://duckduckgo.com/html/")
b.fill("input[name=q]", "servo layout engine")
b.press("Enter")
b.wait("#links")
print(b.read())
Browser methods: open, read, content, url, title, click, dblclick, hover,
focus, type, fill, press, check, uncheck, select, scroll, scroll_into_view,
drag, upload, keyboard_type, wait, eval, screenshot, pdf, cookies,
set_cookie. Failed actions raise julia_browser.BrowserError.
Options: Browser(user_agent=..., javascript=True, js_budget_ms=8000, geolocation=(lat, lon), notifications="granted", settle_ms=2500, websockets=True, service_workers=True).
Password + passkey vault
from julia_browser import Browser, Vault
Vault.import_file("bitwarden.json") # or a CSV from Chrome, Apple Passwords, 1Password, ...
Vault.allow("github.com") # agent use is limited to allowed sites
with Browser() as b:
b.open("https://github.com/login")
b.login(reason="read my notifications") # typed inside the browser; never returned
b.click("input[type=submit]")
b.otp(reason="2FA prompt") # current TOTP code, if the login has one
print(Vault.log()) # what was used, where, when and why
Vault.security_key("github.com") sends a site's WebAuthn to a physical FIDO key or Windows
Hello instead (a person answers the prompt). Passkeys (WebAuthn, with the prf extension) are stored in the same encrypted vault and used by the page's
navigator.credentials calls. See the main README for the encryption details.
One call
import julia_browser as jb
md = jb.render("https://example.com") # markdown (also "text", "html", "layout")
png = jb.screenshot("https://example.com", "example.png")
or from a shell: python -m julia_browser https://example.com -f text.
Puppeteer / Playwright (Chrome DevTools Protocol)
serve_cdp() serves the Chrome DevTools Protocol from your process, so existing Playwright
or Puppeteer code can drive julia-browser instead of Chrome:
import julia_browser
from playwright.sync_api import sync_playwright
server = julia_browser.serve_cdp(port=0) # port=0 picks a free port
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(server.url)
page = browser.contexts[0].new_page()
page.goto("https://news.ycombinator.com")
page.get_by_role("link", name="new", exact=True).click()
print(page.title())
From Node: puppeteer.connect({ browserURL: server.url }). The julia-browser CLI also has
julia-browser cdp --port 9222. serve_cdp() accepts host, javascript=False,
js_budget_ms and user_agent; the server stops when the process exits. Each page opened by
the client gets its own engine thread.
Agent API (julia-browser 2.x compatible)
from julia_browser import AgentSDK
agent = AgentSDK()
page = agent.open_website("https://example.com")
print(page["content"]) # markdown of the page
print(agent.list_elements()["summary"]) # numbered buttons / inputs / links
agent.type_text(1, "hello")
agent.click_element(1)
agent.follow_link(2)
BrowserSDK keeps the 2.x rendering calls (render_to_markdown, fetch_page,
get_page_links, search_page, batch_process, submit_form, ...) and adds
render_to_layout and render_to_png.
Notes
- Each
Browser/AgentSDK/BrowserSDKowns a dedicated engine thread. Calls release the GIL, so several browsers can work in parallel from Python threads. - Cookies and
localStoragepersist in the user profile directory, like a desktop browser.
Metadata
Release files for julia-browser 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| julia_browser-3.0.0-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| julia_browser-3.0.0-cp39-abi3-manylinux_2_35_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.35+ x86-64 | Details |
Total release size: 63.8 MB
Release files / julia_browser-3.0.0-cp39-abi3-win_amd64.whl
| Download URL | julia_browser-3.0.0-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 30.8 MB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
7d489d937dd28b510c74f6dfb3b13f91152e55d45749f570c139228c6486e4eb
|
|
BLAKE2b-256 checksum How to use checksums |
271a0f9d0e75d5c32e262f34478c3c06e5c860ee958451b5a9ef3a7afaaf0a21
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|
Release files / julia_browser-3.0.0-cp39-abi3-manylinux_2_35_x86_64.whl
| Download URL | julia_browser-3.0.0-cp39-abi3-manylinux_2_35_x86_64.whl |
|---|---|
| Size | 33.1 MB |
| Tags | CPython 3.9 Linux glibc 2.35+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
478b690ce6a747959ad48e962e0b17528988d8cc7683b446311239ec8fa79167
|
|
BLAKE2b-256 checksum How to use checksums |
df4e8edc80b065f4140de75aa168acb3bf079f0ef62f6df572b5a75406f8b7bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|
Security for julia-browser 3.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.