### Download and Launch Browser with BrowserFetcher Source: https://context7.com/mattsse/chromiumoxide/llms.txt Automatically downloads and installs a compatible browser version before launching it. Requires the fetcher and zip features enabled. ```rust use std::path::Path; use chromiumoxide::browser::{Browser, BrowserConfig}; use chromiumoxide::fetcher::{BrowserFetcher, BrowserFetcherOptions}; use futures::StreamExt; // Requires features: fetcher, rustls (or native-tls), zip8 (or zip0) #[tokio::main] async fn main() -> Result<(), Box> { // Set up download path let download_path = Path::new("./browser-download"); tokio::fs::create_dir_all(&download_path).await?; // Create fetcher and download browser let fetcher = BrowserFetcher::new( BrowserFetcherOptions::builder() .with_path(&download_path) .build()? ); let info = fetcher.fetch().await?; println!("Browser downloaded to: {:?}", info.executable_path); // Launch the downloaded browser let (browser, mut handler) = Browser::launch( BrowserConfig::builder() .chrome_executable(info.executable_path) .build()? ).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("about:blank").await?; let result: usize = page.evaluate("1 + 1").await?.into_value()?; println!("1 + 1 = {}", result); browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Subscribe to Browser and Page Events in Rust Source: https://context7.com/mattsse/chromiumoxide/llms.txt Listen for various browser and page events such as console logs and page load events. This example demonstrates setting up listeners for console API calls and load events. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use chromiumoxide::cdp::js_protocol::runtime::EventConsoleApiCalled; use chromiumoxide::cdp::browser_protocol::page::EventLoadEventFired; use futures::StreamExt; use std::time::Duration; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch( BrowserConfig::builder().build()? ).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("about:blank").await?; // Listen for console.log calls let mut console_events = page.event_listener::().await?; let logs_handle = tokio::spawn(async move { while let Some(event) = console_events.next().await { println!("Console: {:?} - {:?}", event.r#type, event.args); } }); // Listen for page load events let mut load_events = page.event_listener::().await?; let load_handle = tokio::spawn(async move { while let Some(event) = load_events.next().await { println!("Page loaded at timestamp: {:?}", event.timestamp); } }); page.goto("https://example.com").await?; tokio::time::sleep(Duration::from_secs(2)).await; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Launch Browser in Incognito Mode with Rust Source: https://context7.com/mattsse/chromiumoxide/llms.txt Run browsing sessions in an incognito context for isolated cookies and storage. Two methods are shown: launching directly in incognito mode or starting an incognito context after launch. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { // Option 1: Launch browser in incognito mode let (browser, mut handler) = Browser::launch( BrowserConfig::builder() .incognito() .build()? ).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://example.com").await?; browser.close().await?; handle.await?; // Option 2: Start incognito context after launch let (mut browser, mut handler) = Browser::launch( BrowserConfig::builder().build()? ).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); // Switch to incognito mode let incognito_page = browser .start_incognito_context() .await? .new_page("https://example.com") .await?; // Later, quit incognito context (disposes all incognito pages) browser.quit_incognito_context().await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Cookie Management Source: https://context7.com/mattsse/chromiumoxide/llms.txt Get, set, and delete browser cookies using `set_cookie`, `get_cookies`, and `clear_cookies`. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use chromiumoxide::cdp::browser_protocol::network::CookieParam; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (mut browser, mut handler) = Browser::launch( BrowserConfig::builder().build()? ).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://example.com").await?; // Set a single cookie on the page page.set_cookie(CookieParam::new("session_id", "abc123")).await?; // Set cookie with full options let cookie = CookieParam::builder() .domain(".example.com") .name("tracking_id") .value("xyz789") .path("/") .secure(true) .http_only(true) .build()?; page.set_cookie(cookie).await?; // Get all cookies for the page let cookies = page.get_cookies().await?; for cookie in &cookies { println!("Cookie: {} = {}", cookie.name, cookie.value); } // Browser-level cookie management let all_cookies = browser.get_cookies().await?; browser.clear_cookies().await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Intercept and Modify Network Requests in Rust Source: https://context7.com/mattsse/chromiumoxide/llms.txt Enable request interception in BrowserConfig to block or modify network requests. This example shows how to block requests to a specific domain by fulfilling them with a custom response. ```rust use std::sync::Arc; use base64::Engine; use base64::prelude::BASE64_STANDARD; use chromiumoxide::browser::{Browser, BrowserConfig}; use chromiumoxide::cdp::browser_protocol::fetch::{ ContinueRequestParams, EventRequestPaused, FulfillRequestParams, }; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { // Enable request interception in config let (browser, mut handler) = Browser::launch( BrowserConfig::builder() .enable_request_intercept() .disable_cache() .build()? ).await?; let browser_handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = Arc::new(browser.new_page("about:blank").await?); // Listen for paused requests let mut request_paused = page.event_listener::().await?; let intercept_page = page.clone(); let intercept_handle = tokio::spawn(async move { while let Some(event) = request_paused.next().await { if event.request.url.contains("blocked-domain.com") { // Block request by fulfilling with custom response let _ = intercept_page.execute( FulfillRequestParams::builder() .request_id(event.request_id.clone()) .body(BASE64_STANDARD.encode("

Blocked

")) .response_code(403) .build() .unwrap() ).await; } else { // Continue request normally let _ = intercept_page.execute( ContinueRequestParams::new(event.request_id.clone()) ).await; } } }); page.goto("https://example.com").await?; browser_handle.await?; intercept_handle.await?; Ok(()) } ``` -------------------------------- ### Launch Browser Instance Source: https://context7.com/mattsse/chromiumoxide/llms.txt Initializes a new browser instance using default configuration and spawns a handler to process browser events. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { // Launch headless browser with default settings let (browser, mut handler) = Browser::launch( BrowserConfig::builder().build()? ).await?; // Spawn handler to process browser events let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); // Create a new page let page = browser.new_page("https://example.com").await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Launch Browser and Automate Actions Source: https://github.com/mattsse/chromiumoxide/blob/main/README.md Launches a Chromium instance with a UI, navigates to a page, interacts with elements, and closes the browser. Requires the Tokio runtime. ```rust use futures::StreamExt; use chromiumoxide::browser::{Browser, BrowserConfig}; #[tokio::main] async fn main() -> Result<(), Box> { // create a `Browser` that spawns a `chromium` process running with UI (`with_head()`, headless is default) // and the handler that drives the websocket etc. let (mut browser, mut handler) = Browser::launch(BrowserConfig::builder().with_head().build()?) .await?; // spawn a new task that continuously polls the handler let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); // create a new browser page and navigate to the url let page = browser.new_page("https://en.wikipedia.org").await?; // find and click the search toggle button to reveal the search bar page.find_element(".search-toggle").await?.click().await?; // find the search bar type into the search field and hit `Enter`, // this triggers a new navigation to the search result page page.find_element("input[name='search']") .await? .click() .await? .type_str("Rust programming language") .await? .press_key("Enter") .await?; let html = page.wait_for_navigation().await?.content().await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Download and Configure Chromium with BrowserFetcher Source: https://github.com/mattsse/chromiumoxide/blob/main/README.md Uses the BrowserFetcher to download a Chromium binary and configure a BrowserConfig instance. Requires enabling 'rustls' or 'native-tls' and 'zip0' or 'zip8' features. ```rust use std::path::Path; use futures::StreamExt; use chromiumoxide::browser::{BrowserConfig}; use chromiumoxide::fetcher::{BrowserFetcher, BrowserFetcherOptions}; #[tokio::main] async fn main() -> Result<(), Box> { let download_path = Path::new("./download"); tokio::fs::create_dir_all(&download_path).await?; let fetcher = BrowserFetcher::new( BrowserFetcherOptions::builder() .with_path(&download_path) .build()?, ); let info = fetcher.fetch().await?; let config = BrowserConfig::builder() .chrome_executable(info.executable_path) .build()?, } ``` -------------------------------- ### Inject Scripts Before Page Load Source: https://context7.com/mattsse/chromiumoxide/llms.txt Add initialization scripts that execute before any page scripts run. Use `add_init_script` or `evaluate_on_new_document` for this purpose. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch( BrowserConfig::builder().with_head().build()? ).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("about:blank").await?; // Add init script BEFORE navigation (hides webdriver detection) page.add_init_script(r#" Object.defineProperty(navigator, 'webdriver', { get: () => undefined }); "#).await?; // Alternative: evaluate_on_new_document (same functionality) page.evaluate_on_new_document(r#" window.myGlobalVar = 'initialized'; "#).await?; // Now navigate - scripts will run before page loads page.goto("https://example.com").await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Configure Browser Settings Source: https://context7.com/mattsse/chromiumoxide/llms.txt Uses the BrowserConfig builder to customize browser behavior, including window size, headless mode, and network interception settings. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use std::time::Duration; #[tokio::main] async fn main() -> Result<(), Box> { let config = BrowserConfig::builder() .with_head() // Run with visible UI (non-headless) .window_size(1920, 1080) // Set window dimensions .no_sandbox() // Disable sandbox (required in some environments) .incognito() // Start in incognito mode .launch_timeout(Duration::from_secs(30)) // Custom launch timeout .disable_cache() // Disable browser cache .enable_request_intercept() // Enable network interception .user_data_dir("/tmp/chrome-profile") // Custom user data directory .arg("--disable-gpu") // Add custom Chrome argument .build()?; let (browser, mut handler) = Browser::launch(config).await?; // ... handler and usage code Ok(()) } ``` -------------------------------- ### Generate PDFs with Chromiumoxide Source: https://context7.com/mattsse/chromiumoxide/llms.txt Export web pages as PDF documents. This feature requires headless mode. Options include orientation, background printing, scale, and paper dimensions. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use chromiumoxide_cdp::cdp::browser_protocol::page::PrintToPdfParams; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { // PDF generation requires headless mode let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://news.ycombinator.com/").await?; // Save page as PDF with default settings page.save_pdf(PrintToPdfParams::default(), "page.pdf").await?; // Get PDF as bytes with custom options let pdf_bytes = page.pdf( PrintToPdfParams::builder() .landscape(true) .print_background(true) .scale(0.8) .paper_width(11.0) .paper_height(8.5) .build() .unwrap() ).await?; println!("PDF size: {} bytes", pdf_bytes.len()); browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Interact with Page Elements Source: https://context7.com/mattsse/chromiumoxide/llms.txt Perform common user actions such as clicking elements, typing text, and pressing keys. Use wait_for_navigation to handle page transitions after interactions. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch( BrowserConfig::builder().with_head().build()? ).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://en.wikipedia.org").await?; // Click the search toggle button page.find_element(".search-toggle").await?.click().await?; // Find input, click it, type text, and press Enter page.find_element("input[name='search']") .await? .click() .await? .type_str("Rust programming language") .await? .press_key("Enter") .await?; // Wait for navigation after form submission let html = page.wait_for_navigation().await?.content().await?; println!("Page content length: {} bytes", html.len()); browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Navigate Pages Source: https://context7.com/mattsse/chromiumoxide/llms.txt Performs navigation tasks such as loading URLs, waiting for navigation events, and reloading the current page. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://example.com").await?; // Navigate to a new URL page.goto("https://news.ycombinator.com/").await?; // Wait for navigation to complete after an action page.wait_for_navigation().await?; // Get the current URL let url = page.url().await?; println!("Current URL: {:?}", url); // Reload the page page.reload().await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Connect to Existing Browser Source: https://context7.com/mattsse/chromiumoxide/llms.txt Connects to a running Chrome instance using either a direct WebSocket URL or an HTTP endpoint for auto-discovery. ```rust use chromiumoxide::browser::Browser; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { // Connect via WebSocket URL let (browser, mut handler) = Browser::connect( "ws://127.0.0.1:9222/devtools/browser/abc123" ).await?; // Or connect via HTTP endpoint (auto-discovers WebSocket URL) let (browser, mut handler) = Browser::connect( "http://127.0.0.1:9222" ).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://example.com").await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Page PDF Generation Wrapper Source: https://github.com/mattsse/chromiumoxide/blob/main/README.md A simplified wrapper function for generating a PDF of a page using the DevTools Protocol. It decodes the base64 data returned by the command. ```rust pub async fn pdf(&self, params: PrintToPdfParams) -> Result> { let res = self.execute(params).await?; Ok(base64::decode(&res.data)?) } ``` -------------------------------- ### Execute Raw CDP Commands Source: https://context7.com/mattsse/chromiumoxide/llms.txt Directly invoke Chrome DevTools Protocol commands for advanced browser control. Requires importing specific parameter structs from chromiumoxide_cdp. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use chromiumoxide_cdp::cdp::browser_protocol::page::ReloadParams; use chromiumoxide_cdp::cdp::browser_protocol::emulation::SetGeolocationOverrideParams; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://example.com").await?; // Execute any CDP command via page.execute() page.execute(ReloadParams::builder().ignore_cache(true).build()).await?; page.wait_for_navigation().await?; // Emulate geolocation page.execute( SetGeolocationOverrideParams::builder() .latitude(37.7749) .longitude(-122.4194) .accuracy(100.0) .build() ).await?; // Get browser version info let version = browser.version().await?; println!("Browser: {} v{}", version.product, version.revision); browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Stealth Mode for Bot Detection Avoidance Source: https://context7.com/mattsse/chromiumoxide/llms.txt Enable stealth mode to make browser automation harder to detect. Use `hide()` during launch or `enable_stealth_mode()` on a page. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { // Use 'hide' option to disable automation detection at launch let config = BrowserConfig::builder() .with_head() .hide() // Disables AutomationControlled blink feature .build()?; let (browser, mut handler) = Browser::launch(config).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://example.com").await?; // Enable comprehensive stealth mode (modifies navigator properties, plugins, etc.) page.enable_stealth_mode().await?; // Or with custom user agent page.enable_stealth_mode_with_agent( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" ).await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Take Screenshots with Chromiumoxide Source: https://context7.com/mattsse/chromiumoxide/llms.txt Capture full-page or element-specific screenshots in various formats. Options include format, omitting background, and quality settings. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use chromiumoxide::page::ScreenshotParams; use chromiumoxide_cdp::cdp::browser_protocol::page::CaptureScreenshotFormat; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://news.ycombinator.com/").await?; // Take full page screenshot with options page.save_screenshot( ScreenshotParams::builder() .format(CaptureScreenshotFormat::Png) .full_page(true) .omit_background(true) .build(), "full-page.png", ).await?; // Take screenshot of specific element let element = page.find_element("table.itemlist tr").await?; element.save_screenshot(CaptureScreenshotFormat::Png, "element.png").await?; // Get screenshot as bytes without saving let screenshot_bytes = page.screenshot( ScreenshotParams::builder() .format(CaptureScreenshotFormat::Jpeg) .quality(80) .build() ).await?; println!("Screenshot size: {} bytes", screenshot_bytes.len()); browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Manipulate Page Content Source: https://context7.com/mattsse/chromiumoxide/llms.txt Inject HTML content into a page and retrieve current page state or metadata. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("about:blank").await?; // Set page HTML content page.set_content(r#" Custom Page

Hello from chromiumoxide!

This content was injected

"#).await?; // Get page title let title = page.get_title().await?; println!("Title: {:?}", title); // Output: Title: Some("Custom Page") // Get full HTML content let html = page.content().await?; println!("Content length: {} bytes", html.len()); browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Evaluate JavaScript with Chromiumoxide Source: https://context7.com/mattsse/chromiumoxide/llms.txt Execute JavaScript code within the browser's page context and retrieve results. Supports simple expressions, arrow functions, promises, and async functions. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use chromiumoxide_cdp::cdp::js_protocol::runtime::{CallArgument, CallFunctionOnParams}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("about:blank").await?; // Evaluate simple expression let sum: usize = page.evaluate("1 + 2").await?.into_value()?; println!("1 + 2 = {}", sum); // Output: 1 + 2 = 3 // Evaluate arrow function let mult: usize = page.evaluate("() => { return 21 * 2; }").await?.into_value()?; println!("21 * 2 = {}", mult); // Output: 21 * 2 = 42 // Evaluate promise let result: usize = page.evaluate("() => Promise.resolve(100 / 25)").await?.into_value()?; println!("100 / 25 = {}", result); // Output: 100 / 25 = 4 // Evaluate async function let val: usize = page.evaluate_function("async function() { return 42; }").await?.into_value()?; println!("async result = {}", val); // Call function with arguments let call = CallFunctionOnParams::builder() .function_declaration("(a, b) => { return a + b; }") .argument(CallArgument::builder().value(serde_json::json!(10)).build()) .argument(CallArgument::builder().value(serde_json::json!(20)).build()) .build() .unwrap(); let sum: usize = page.evaluate_function(call).await?.into_value()?; println!("10 + 20 = {}", sum); // Output: 10 + 20 = 30 browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Find Elements with CSS Selectors and XPath Source: https://context7.com/mattsse/chromiumoxide/llms.txt Locate single or multiple elements on a page using CSS selectors or XPath expressions. Requires an active browser page instance. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://news.ycombinator.com/").await?; // Find a single element let title = page.find_element("a.titleline").await?; // Find multiple elements let all_links = page.find_elements("a.titleline").await?; println!("Found {} story links", all_links.len()); // Find element within another element let container = page.find_element("table.itemlist").await?; let first_row = container.find_element("tr").await?; // Find elements using XPath let xpath_element = page.find_xpath("//a[@class='titleline']").await?; browser.close().await?; handle.await?; Ok(()) } ``` -------------------------------- ### Extract Element Properties and Attributes Source: https://context7.com/mattsse/chromiumoxide/llms.txt Retrieve text, HTML content, specific attributes, or JavaScript properties from DOM elements. These methods return results asynchronously. ```rust use chromiumoxide::browser::{Browser, BrowserConfig}; use futures::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let (browser, mut handler) = Browser::launch(BrowserConfig::builder().build()?).await?; let handle = tokio::spawn(async move { while let Some(h) = handler.next().await { if h.is_err() { break; } } }); let page = browser.new_page("https://example.com").await?; let element = page.find_element("h1").await?; // Get inner text let text = element.inner_text().await?; println!("Text: {:?}", text); // Get inner HTML let inner_html = element.inner_html().await?; println!("Inner HTML: {:?}", inner_html); // Get outer HTML (includes the element itself) let outer_html = element.outer_html().await?; println!("Outer HTML: {:?}", outer_html); // Get specific attribute let link = page.find_element("a").await?; let href = link.attribute("href").await?; println!("Link href: {:?}", href); // Get all attributes let attrs = link.attributes().await?; println!("All attributes: {:?}", attrs); // Get JavaScript property let value = element.property("tagName").await?; println!("Tag name: {:?}", value); browser.close().await?; handle.await?; Ok(()) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.