use browsing::browser::{Browser, BrowserProfile};
use browsing::error::Result;
use std::env;
use std::path::Path;
async fn get_page_text(browser: &Browser, max_chars: usize) -> Result<String> {
let page = browser.get_page()?;
let expr = format!(
"(document.body?.innerText || document.body?.textContent || '').slice(0, {})",
max_chars
);
page.evaluate(&expr).await
}
async fn get_page_title(browser: &Browser) -> Result<String> {
let page = browser.get_page()?;
page.evaluate("document.title").await
}
async fn get_first_different_link_href(
browser: &Browser,
current_url: &str,
) -> Result<Option<String>> {
let page = browser.get_page()?;
let current_escaped = serde_json::to_string(current_url).unwrap_or_else(|_| "\"\"".to_string());
let script = format!(
r#"
(function() {{
const current = {};
const links = Array.from(document.querySelectorAll('a[href]'))
.filter(a => a.href && !a.href.startsWith('javascript:'))
.map(a => a.href);
const found = links.find(href => href !== current);
return found ? JSON.stringify(found) : 'null';
}})()
"#,
current_escaped
);
let result = page.evaluate(&script).await?;
Ok(serde_json::from_str::<Option<String>>(&result).unwrap_or(None))
}
#[tokio::main]
async fn main() -> Result<()> {
browsing::init();
let headless = env::var("BROWSER_USE_HEADLESS")
.ok()
.and_then(|v| v.parse::<bool>().ok())
.unwrap_or(false);
println!("═══ Comprehensive Browse Example ═══\n");
println!(" Browse → Navigate → Get Text → Get Image\n");
let profile = BrowserProfile {
headless: Some(headless),
..Default::default()
};
println!("1️⃣ Starting browser...");
let mut browser = Browser::new(profile);
browser.start().await?;
println!(" ✓ Browser ready\n");
let url1 = "https://example.com";
println!("2️⃣ Navigating to {}...", url1);
browser.navigate(url1).await?;
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
let url = browser.get_current_url().await?;
let title = get_page_title(&browser).await.unwrap_or_else(|_| "".into());
println!(" ✓ Loaded: {} ({})\n", title, url);
println!("3️⃣ Extracting text content...");
let text = get_page_text(&browser, 2000).await?;
let preview: String = text.chars().take(300).collect();
println!(" 📄 Text preview ({} chars total):", text.len());
println!(" ┌─────────────────────────────────────────");
for line in preview.lines().take(8) {
println!(" │ {}", line);
}
if text.len() > 300 {
println!(" │ ...");
}
println!(" └─────────────────────────────────────────\n");
let screenshot1 = "example_com_screenshot.png";
println!("4️⃣ Taking screenshot...");
browser
.take_screenshot(Some(screenshot1), false, None, None)
.await?;
println!(" ✓ Image saved: {}\n", screenshot1);
let url2 = "https://www.rust-lang.org";
println!("5️⃣ Navigating to {}...", url2);
browser.navigate(url2).await?;
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
let url = browser.get_current_url().await?;
let title2 = get_page_title(&browser).await.unwrap_or_else(|_| "".into());
println!(" ✓ Loaded: {} ({})\n", title2, url);
println!("5a️⃣ Following first link (skipping same-URL links)...");
if let Some(href) = get_first_different_link_href(&browser, &url).await? {
browser.navigate(&href).await?;
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
let followed_url = browser.get_current_url().await?;
println!(" ✓ Followed to: {}\n", followed_url);
} else {
println!(" ⚠ No links found, staying on page\n");
}
println!("6️⃣ Extracting text from Rust page...");
let text2 = get_page_text(&browser, 2000).await?;
let preview2: String = text2.chars().take(250).collect();
println!(" 📄 Text preview ({} chars total):", text2.len());
println!(" ┌─────────────────────────────────────────");
for line in preview2.lines().take(6) {
println!(" │ {}", line);
}
if text2.len() > 250 {
println!(" │ ...");
}
println!(" └─────────────────────────────────────────\n");
let screenshot2 = "rust_lang_screenshot.png";
println!("7️⃣ Taking screenshot...");
browser
.take_screenshot(Some(screenshot2), false, None, None)
.await?;
println!(" ✓ Image saved: {}\n", screenshot2);
println!("═══ Done ═══");
println!(" Screenshots: {}, {}", screenshot1, screenshot2);
println!(" Text extracted from 2 pages");
if Path::new(screenshot1).exists() {
println!(" 💡 Open {} to view the captured image", screenshot1);
}
if !headless {
println!("\n Keeping browser open 3 seconds...");
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
}
println!("\n Closing browser...");
browser.stop().await?;
println!(" ✓ Browser closed gracefully");
Ok(())
}