Rust浏览器自动化库chromiumoxide_types的使用,Chromiumoxide_types为Rust开发者提供类型安全的浏览器控制与交互功能

Rust浏览器自动化库chromiumoxide_types的使用

chromiumoxide是一个Rust库,它通过Chrome DevTools协议提供了控制Chrome/Chromium浏览器的高级异步API。以下是基于您提供内容的完整整理:

基本使用示例

use futures::StreamExt;
use chromiumoxide::browser::{Browser, BrowserConfig};

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 创建带UI的浏览器实例(默认无头模式)
    let (mut browser, mut handler) =
        Browser::launch(BrowserConfig::builder().with_head().build()?).await?;
    
    // 创建任务处理浏览器事件
    let handle = async_std::task::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?;
    
    // 查找元素并交互
    page.find_element("input#searchInput")
        .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(())
}

完整功能示例

use futures::StreamExt;
use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::page::PrintToPdfParams;
use chromiumoxide::fetcher::{BrowserFetcher, BrowserFetcherOptions};
use std::path::Path;

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 自动下载Chromium
    let download_path = Path::new("./download");
    async_std::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()
        .with_head() // 启用UI
        .chrome_executable(info.executable_path)
        .build()?;
        
    let (mut browser, mut handler) = Browser::launch(config).await?;
    
    // 处理浏览器事件
    let handle = async_std::task::spawn(async move {
        while let Some(h) = handler.next().await {
            if h.is_err() {
                break;
            }
        }
    });
    
    // 页面操作
    let page = browser.new_page("https://example.com").await?;
    
    // 点击标题元素
    page.find_element("h1")
        .await?
        .click()
        .await?;
        
    // 生成PDF
    let pdf_params = PrintToPdfParams::builder()
        .landscape(true)
        .build();
    let pdf_data = page.pdf(pdf_params).await?;
    
    // 关闭浏览器
    browser.close().await?;
    handle.await;
    
    Ok(())
}

项目集成

在Cargo.toml中添加依赖:

[dependencies]
# 使用async-std运行时
chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", branch = "main"}

# 或使用tokio运行时
chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", features = ["tokio-runtime"], default-features = false, branch = "main"}

核心特性

  1. 类型安全API:所有操作都有严格的类型检查
  2. 灵活配置:支持无头/有界面模式,可连接现有实例
  3. 自动下载:内置Chromium自动下载功能
  4. 多运行时支持:同时支持async-std和tokio

常见问题解决方案

  1. 启动超时问题:确保Chromium设置为英语界面
  2. 编译错误:不要设置CDP_NO_EXPERIMENTAL环境变量
  3. 元素查找失败:确保使用正确的CSS选择器并等待元素加载完成

这个库非常适合需要浏览器自动化的Rust项目,如网页测试、爬虫、PDF生成等场景。


1 回复

Rust浏览器自动化库chromiumoxide_types使用指南

chromiumoxide_types是Rust中用于浏览器自动化的类型安全库,它提供了与Chromium浏览器交互所需的类型定义和基本功能。

主要功能

  • 类型安全的浏览器控制接口
  • 与Chromium DevTools Protocol交互的类型定义
  • 异步/同步浏览器操作支持
  • 页面导航、元素操作、JavaScript执行等功能

基本使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
chromiumoxide = "0.7"
chromiumoxide_types = "0.7"
tokio = { version = "1.0", features = ["full"] }

基本示例

use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::page::Page;
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 启动浏览器
    let (browser, mut handler) = Browser::launch(BrowserConfig::default()).await?;
    
    // 处理浏览器事件的任务
    tokio::spawn(async move {
        while let Some(h) = handler.next().await {
            if h.is_err() {
                break;
            }
        }
    });
    
    // 创建新页面
    let page: Page = browser.new_page("https://example.com").await?;
    
    // 等待页面完全加载
    page.wait_for_navigation().await?;
    
    // 执行JavaScript并获取结果
    let title: String = page.evaluate("document.title").await?.into_value()?;
    println!("页面标题: {}", title);
    
    Ok(())
}

高级功能

元素操作

// 查找元素并点击
let elem = page.find_element("button#submit").await?;
elem.click().await?;

// 输入文本
let input = page.find_element("input[name='username']").await?;
input.send_keys("rust_user").await?;

处理弹窗

use chromiumoxide::handler::Handler;
use chromiumoxide_types::Event;

let handler = Handler::new()
    .on(Event::DialogOpened, |dialog| async move {
        println!("对话框消息: {}", dialog.message());
        dialog.accept().await?;
        Ok(())
    });

网络拦截

use chromiumoxide_types::Fetch;

page.enable_fetch(Some(Fetch::Params {
    patterns: vec![Fetch::Pattern {
        url_pattern: Some("*.png".to_string()),
        ..Default::default()
    }],
    handle: true,
    ..Default::default()
})).await?;

page.on_fetch_request(|req| async move {
    if req.url().ends_with(".png") {
        req.fail().await?;
    } else {
        req.continue_().await?;
    }
    Ok(())
}).await?;

类型安全示例

chromiumoxide_types提供了丰富的类型定义:

use chromiumoxide_types::{
    page::NavigateParams,
    runtime::{CallFunctionOnParams, RemoteObject},
};

// 类型安全的导航参数
let nav_params = NavigateParams::builder()
    .url("https://example.com")
    .referrer("https://google.com")
    .build()?;

// 类型安全的JavaScript执行
let js_params = CallFunctionOnParams::builder()
    .function_declaration("() => { return {a: 1, b: 'test'}; }")
    .build()?;

let result: RemoteObject = page.execute(js_params).await?;

完整示例demo

下面是一个整合了多个功能的完整示例:

use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::page::Page;
use chromiumoxide::handler::Handler;
use chromiumoxide_types::{Event, Fetch};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 配置浏览器启动参数
    let config = BrowserConfig::builder()
        .headless(true)  // 无头模式
        .build()?;
    
    // 启动浏览器
    let (browser, mut handler) = Browser::launch(config).await?;
    
    // 处理浏览器事件的任务
    let handle_events = tokio::spawn(async move {
        while let Some(h) = handler.next().await {
            if h.is_err() {
                break;
            }
        }
    });
    
    // 设置弹窗处理器
    let handler = Handler::new()
        .on(Event::DialogOpened, |dialog| async move {
            println!("检测到弹窗: {}", dialog.message());
            dialog.accept().await?;
            Ok(())
        });
    
    // 创建新页面
    let page: Page = browser.new_page("https://example.com").await?;
    
    // 等待页面加载
    page.wait_for_navigation().await?;
    
    // 拦截图片请求
    page.enable_fetch(Some(Fetch::Params {
        patterns: vec![Fetch::Pattern {
            url_pattern: Some("*.png".to_string()),
            ..Default::default()
        }],
        handle: true,
        ..Default::default()
    })).await?;
    
    page.on_fetch_request(|req| async move {
        if req.url().ends_with(".png") {
            println!("拦截图片请求: {}", req.url());
            req.fail().await?;
        } else {
            req.continue_().await?;
        }
        Ok(())
    }).await?;
    
    // 获取页面标题
    let title: String = page.evaluate("document.title").await?.into_value()?;
    println!("页面标题: {}", title);
    
    // 模拟用户操作
    page.evaluate("document.body.innerHTML = '<input id=\"username\"/><button id=\"submit\">Submit</button>'")
        .await?;
    
    let input = page.find_element("input#username").await?;
    input.send_keys("rust_user").await?;
    
    let button = page.find_element("button#submit").await?;
    button.click().await?;
    
    // 关闭浏览器
    browser.close().await?;
    handle_events.await?;
    
    Ok(())
}

注意事项

  1. 需要系统中已安装Chromium或Chrome浏览器
  2. 异步操作需要使用async/await语法
  3. 错误处理很重要,大多数操作都可能失败
  4. 资源使用后需要正确关闭以避免内存泄漏

chromiumoxide_types为Rust开发者提供了强大且类型安全的浏览器自动化能力,适合构建爬虫、自动化测试、网页截图等应用。

回到顶部