use std::collections::HashMap;
use std::time::Duration;
use crawlkit::{Collector, CompositeFetcher, HttpClient, ReqwestClient};
use crawlkit_extensions::cdp::{CdpClient, CdpPool, CdpStrategy};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("=== CDP 无头浏览器示例 ===\n");
println!("--- 1. 单端点 CdpClient ---\n");
let cdp = CdpClient::builder()
.with_endpoint("http://127.0.0.1:9222")
.with_navigation_timeout(Duration::from_secs(15))
.build()
.await?;
let resp = cdp.get("https://example.com", &HashMap::new()).await?;
println!(" URL: {}", resp.url);
println!(" 长度: {} 字节\n", resp.body.len());
println!("--- 2. CdpPool 轮询(RoundRobin)---\n");
let pool = CdpPool::builder()
.with_named_endpoint("lightpanda", "http://127.0.0.1:9222")
.with_named_endpoint("obscura", "http://127.0.0.1:9223")
.with_strategy(CdpStrategy::RoundRobin)
.with_navigation_timeout(Duration::from_secs(15))
.build()
.await?;
println!(" 健康端点: {}/{}", pool.healthy_count().await, pool.total_count().await);
for i in 0..4 {
let resp = pool.get("https://httpbin.org/ip", &HashMap::new()).await?;
println!(" 请求 {}: {} ({} 字节)", i + 1, resp.url, resp.body.len());
}
println!("\n--- 3. CdpPool 随机(Random)---\n");
let pool_random = CdpPool::builder()
.with_endpoint("http://127.0.0.1:9222")
.with_endpoint("http://127.0.0.1:9223")
.with_strategy(CdpStrategy::Random)
.build()
.await?;
for i in 0..3 {
let resp = pool_random.get("https://example.com", &HashMap::new()).await?;
println!(" 请求 {}: {} 字节", i + 1, resp.body.len());
}
println!("\n--- 4. CdpPool 故障转移(Failover)---\n");
let pool_failover = CdpPool::builder()
.with_named_endpoint("primary", "http://127.0.0.1:9222")
.with_named_endpoint("backup", "http://127.0.0.1:9223")
.with_strategy(CdpStrategy::Failover)
.build()
.await?;
let resp = pool_failover.get("https://example.com", &HashMap::new()).await?;
println!(" 获取成功: {} 字节", resp.body.len());
println!("\n--- 5. CompositeFetcher 集成 ---\n");
let fetcher = CompositeFetcher::new(vec![
Box::new(ReqwestClient::builder().name("reqwest").build()?),
Box::new(
CdpPool::builder()
.with_endpoint("http://127.0.0.1:9222")
.with_strategy(CdpStrategy::Failover)
.build()
.await?,
),
])
.on_backend_error(|name, err| {
eprintln!(" [{}] 失败: {}", name, err);
});
let mut collector = Collector::with_client(fetcher);
collector.on_html(|ctx| {
println!(" [HTML] {} - {} 字节", ctx.url, ctx.body.len());
});
collector.visit("https://news.ycombinator.com/").await?;
Ok(())
}