pub struct PageHandle { /* private fields */ }Expand description
§Example
use stygian_browser::{BrowserPool, BrowserConfig};
use stygian_browser::page::WaitUntil;
use std::time::Duration;
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;
let html = page.content().await?;
drop(page); // closes the tab
handle.release().await;Implementations§
Source§impl PageHandle
impl PageHandle
§Errors
the CDP call fails.
Sourcepub async fn wait_for_selector(
&self,
selector: &str,
wait_timeout: Duration,
) -> Result<()>
pub async fn wait_for_selector( &self, selector: &str, wait_timeout: Duration, ) -> Result<()>
§Errors
within the given timeout.
Sourcepub async fn set_resource_filter(
&mut self,
filter: ResourceFilter,
) -> Result<()>
pub async fn set_resource_filter( &mut self, filter: ResourceFilter, ) -> Result<()>
Enables Fetch interception and spawns a background task that continues
allowed requests and fails blocked ones with BlockedByClient. Any
previously set filter task is cancelled first.
§Errors
Sourcepub async fn url(&self) -> Result<String>
pub async fn url(&self) -> Result<String>
Return the current page URL (post-navigation, post-redirect).
internally by save_cookies; no extra network
request is made. Returns an empty string if the URL is not yet set
§Errors
BrowserError::Timeout if it exceeds cdp_timeout.
§Example
use stygian_browser::{BrowserPool, BrowserConfig};
use stygian_browser::page::WaitUntil;
use std::time::Duration;
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;
let url = page.url().await?;
println!("Final URL after redirects: {url}");Sourcepub fn status_code(&self) -> Result<Option<u16>>
pub fn status_code(&self) -> Result<Option<u16>>
Return the HTTP status code of the most recent main-frame navigation.
The status is captured from the Network.responseReceived CDP event
wired up inside navigate, so it reflects the
final response after any server-side redirects.
navigations, when navigate has not yet been called,
or if the network event subscription failed.
§Errors
§Example
use stygian_browser::{BrowserPool, BrowserConfig};
use stygian_browser::page::WaitUntil;
use std::time::Duration;
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;
if let Some(code) = page.status_code()? {
println!("HTTP {code}");
}Sourcepub async fn query_selector_all(
&self,
selector: &str,
) -> Result<Vec<NodeHandle>>
pub async fn query_selector_all( &self, selector: &str, ) -> Result<Vec<NodeHandle>>
lightweight NodeHandles backed by CDP RemoteObjectIds.
No HTML serialisation occurs — the browser’s in-memory DOM is queried
directly over the CDP connection, eliminating the page.content() +
scraper::Html::parse_document round-trip.
§Errors
BrowserError::Timeout if it exceeds cdp_timeout.
§Example
use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
use std::time::Duration;
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;
let ux_type = node.attr("data-ux").await?;
let text = node.text_content().await?;
println!("{ux_type:?}: {text}");Sourcepub async fn eval<T: DeserializeOwned>(&self, script: &str) -> Result<T>
pub async fn eval<T: DeserializeOwned>(&self, script: &str) -> Result<T>
§Errors
SessionSnapshot and without
requiring a direct chromiumoxide dependency in calling code.
Individual cookie failures are logged as warnings and do not abort the remaining cookies.
§Errors
call exceeds cdp_timeout.
§Example
use stygian_browser::{BrowserPool, BrowserConfig};
use stygian_browser::session::SessionCookie;
use std::time::Duration;
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let page = handle.browser().expect("valid browser").new_page().await?;
let cookies = vec![SessionCookie {
name: "session".to_string(),
value: "abc123".to_string(),
domain: ".example.com".to_string(),
path: "/".to_string(),
expires: -1.0,
http_only: true,
secure: true,
same_site: "Lax".to_string(),
}];
page.inject_cookies(&cookies).await?;Sourcepub async fn screenshot(&self) -> Result<Vec<u8>>
pub async fn screenshot(&self) -> Result<Vec<u8>>
Capture a screenshot of the current page as PNG bytes.
them in-memory.
§Errors
command fails, or BrowserError::Timeout if it exceeds
cdp_timeout.
§Example
use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
use std::{time::Duration, fs};
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
let png = page.screenshot().await?;
fs::write("screenshot.png", &png).unwrap();Source§impl PageHandle
impl PageHandle
Sourcepub async fn verify_stealth(&self) -> Result<DiagnosticReport>
pub async fn verify_stealth(&self) -> Result<DiagnosticReport>
Run all built-in stealth detection checks against the current page.
Iterates crate::diagnostic::all_checks, evaluates each check’s
JavaScript via CDP Runtime.evaluate, and returns an aggregate
crate::diagnostic::DiagnosticReport.
recorded as failing checks and do not abort the whole run.
§Errors
Individual check failures are captured in the report.
§Example
use stygian_browser::{BrowserPool, BrowserConfig};
use stygian_browser::page::WaitUntil;
use std::time::Duration;
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let browser = handle.browser().expect("valid browser");
let mut page = browser.new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(10)).await?;
let report = page.verify_stealth().await?;
println!("Stealth: {}/{} checks passed", report.passed_count, report.checks.len());
eprintln!(" FAIL {}: {}", failure.description, failure.details);Sourcepub async fn verify_stealth_with_transport(
&self,
observed: Option<TransportObservations>,
) -> Result<DiagnosticReport>
pub async fn verify_stealth_with_transport( &self, observed: Option<TransportObservations>, ) -> Result<DiagnosticReport>
Run stealth checks and attach transport diagnostics (JA3/JA4/HTTP3).
Source§impl PageHandle
impl PageHandle
Sourcepub async fn extract_all<T>(&self, selector: &str) -> Result<Vec<T>>where
T: Extractable,
pub async fn extract_all<T>(&self, selector: &str) -> Result<Vec<T>>where
T: Extractable,
All per-node extractions are driven concurrently via
[futures::future::try_join_all].
§Errors
fails, or BrowserError::ExtractionFailed if any field extraction
fails.
§Example
use stygian_browser::extract::Extract;
use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
use std::time::Duration;
#[derive(Extract)]
struct Link {
href: Option<String>,
}
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate(
"https://example.com",
WaitUntil::DomContentLoaded,
Duration::from_secs(30),
).await?;
let links: Vec<Link> = page.extract_all::<Link>("nav li").await?;Sourcepub async fn extract_all_with_fallback<T>(
&self,
selectors: &[&str],
) -> Result<Vec<T>>where
T: Extractable,
pub async fn extract_all_with_fallback<T>(
&self,
selectors: &[&str],
) -> Result<Vec<T>>where
T: Extractable,
Try each selector in selectors in order and return the extracted
results from the first selector that matches at least one node.
This is useful when a page may use different markup across versions or A/B variants — supply the preferred selector first and progressively wider fallbacks afterwards.
Returns an empty Vec only when all selectors match zero nodes
(i.e. the element is genuinely absent from the page). A non-empty
intermediate selector result that then fails during extraction will
return an error.
§Errors
Returns BrowserError::CdpError if the selector query fails, or
BrowserError::ExtractionFailed if a matched node fails extraction.
§Example
use stygian_browser::extract::Extract;
#[derive(Extract)]
struct Headline { title: String }
// Try modern selector first, fall back to legacy markup.
let items = page
.extract_all_with_fallback::<Headline>(&["h2.headline", "h2.title", "h2"])
.await?;Sourcepub async fn extract_resilient<T>(&self, selector: &str) -> Result<Vec<T>>where
T: Extractable,
pub async fn extract_resilient<T>(&self, selector: &str) -> Result<Vec<T>>where
T: Extractable,
Extract from every node matching selector, skipping nodes where
a required field is absent (i.e. ExtractionError::Missing).
Unlike extract_all, this method is lenient about structural
mismatches: nodes that fail with ExtractionError::Missing are
silently dropped from the result set. All other extraction errors
(CDP failures, stale nodes, nested errors) still propagate as hard
failures.
This is useful when scraping heterogeneous lists where some items lack an optional field that your struct treats as required.
§Errors
Returns BrowserError::CdpError if the selector query fails, or
BrowserError::ExtractionFailed for non-Missing extraction errors.
§Example
use stygian_browser::extract::Extract;
#[derive(Extract)]
struct Price { amount: String }
// Products without a price tag are silently skipped.
let prices = page.extract_resilient::<Price>(".product").await?;Source§impl PageHandle
impl PageHandle
Sourcepub async fn find_similar(
&self,
reference: &NodeHandle,
config: SimilarityConfig,
) -> Result<Vec<SimilarMatch>>
pub async fn find_similar( &self, reference: &NodeHandle, config: SimilarityConfig, ) -> Result<Vec<SimilarMatch>>
reference, scored by crate::similarity::SimilarityConfig.
NodeHandle::fingerprint), then fingerprints every candidate returned
crate::similarity::jaccard_weighted score exceeds
config.threshold. Results are ordered by score descending.
§Example
use stygian_browser::{BrowserPool, BrowserConfig, WaitUntil};
use stygian_browser::similarity::SimilarityConfig;
use std::time::Duration;
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate("https://example.com", WaitUntil::DomContentLoaded, Duration::from_secs(30)).await?;
let similar = page.find_similar(&reference, SimilarityConfig::default()).await?;
println!("score={:.2}", m.score);§Errors
BrowserError::ScriptExecutionFailed if a scoring script fails.
Source§impl PageHandle
impl PageHandle
Sourcepub async fn warmup(&mut self, options: WarmupOptions) -> Result<WarmupReport>
pub async fn warmup(&mut self, options: WarmupOptions) -> Result<WarmupReport>
Warm up a browser session by navigating to options.url and
optionally waiting for dynamic resources to settle.
Warmup is idempotent: calling it repeatedly re-navigates and re-warms the same session without adverse side effects.
§Errors
Returns BrowserError::NavigationFailed if the navigation times out
or the underlying CDP call fails.
§Example
use stygian_browser::{BrowserPool, BrowserConfig};
use stygian_browser::page::{WarmupOptions, WarmupWait};
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
let report = page.warmup(WarmupOptions {
url: "https://example.com".to_string(),
wait: WarmupWait::DomContentLoaded,
timeout_ms: 30_000,
stabilize_ms: 500,
}).await?;
println!("warmed in {}ms: {}", report.elapsed_ms, report.title);
handle.release().await;Sourcepub async fn refresh(
&mut self,
options: RefreshOptions,
) -> Result<RefreshReport>
pub async fn refresh( &mut self, options: RefreshOptions, ) -> Result<RefreshReport>
Refresh the current page, retaining all in-browser session state
(cookies, localStorage, sessionStorage).
When options.reset_connection is false (default) a standard
CDP reload is issued. When true, the current URL is re-navigated,
which expresses the caller’s intent to force a new underlying TCP/TLS
connection while keeping all browser-side state intact.
Refresh is idempotent: repeated calls simply reload the page again.
§Errors
Returns BrowserError::NavigationFailed if the current URL cannot be
determined or the reload times out.
§Example
use stygian_browser::{BrowserPool, BrowserConfig};
use stygian_browser::page::{RefreshOptions, WaitUntil};
let pool = BrowserPool::new(BrowserConfig::default()).await?;
let handle = pool.acquire().await?;
let mut page = handle.browser().expect("valid browser").new_page().await?;
page.navigate(
"https://example.com",
WaitUntil::DomContentLoaded,
std::time::Duration::from_secs(30),
).await?;
let report = page.refresh(RefreshOptions::default()).await?;
println!("refreshed in {}ms", report.elapsed_ms);
handle.release().await;