#chrome #自动化 #puppeteer #chromedriver #包装器 #WebSocket

chromiumoxide

使用 Chrome DevTools 协议与 Chrome 实例交互的库

16 个不稳定版本 (6 个破坏性更新)

0.7.0 2024 年 8 月 12 日
0.6.0 2024 年 5 月 28 日
0.5.7 2023 年 12 月 29 日
0.5.6 2023 年 11 月 7 日
0.1.0 2020 年 12 月 13 日

#32网页编程

Download history 1142/week @ 2024-05-04 1146/week @ 2024-05-11 1025/week @ 2024-05-18 1381/week @ 2024-05-25 1424/week @ 2024-06-01 1328/week @ 2024-06-08 1310/week @ 2024-06-15 1069/week @ 2024-06-22 1315/week @ 2024-06-29 1354/week @ 2024-07-06 2162/week @ 2024-07-13 1778/week @ 2024-07-20 1700/week @ 2024-07-27 1232/week @ 2024-08-03 1812/week @ 2024-08-10 2046/week @ 2024-08-17

7,054 每月下载量
用于 24 个 Crates (17 个直接使用)

MIT/Apache

5MB
107K SLoC

chromiumoxide

Build Crates.io Documentation

chromiumoxide 提供了一个高级和异步 API,用于通过 DevTools 协议 控制 Chrome 或 Chromium。它支持所有类型的 Chrome DevTools 协议,可以启动一个 无头 或完整(非无头)Chrome 或 Chromium 实例,或连接到一个已运行的实例。

用法

use futures::StreamExt;

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

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    
   // 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 = async_std::task::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 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#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(())
}

当前的 API 还缺少一些功能,但 Page::execute 函数允许发送所有 chromiumoxide_types::Command 类型(见 生成的代码)。大多数 ElementPage 函数基本上只是简化的命令构造和组合,例如 Page::pdf

pub async fn pdf(&self, params: PrintToPdfParams) -> Result<Vec<u8>> {
     let res = self.execute(params).await?;
     Ok(base64::decode(&res.data)?)
 }

如果你需要其他功能,Page::execute 函数允许你编写自己的命令包装器。如果你认为缺少一个有意义的命令函数,非常欢迎提交 PR。

将 chromiumoxide 添加到你的项目中

chromiumoxide 内置了对 async-stdtokio 运行时的支持。

默认情况下,chromiumoxide 配置为使用 async-std

使用 chromiumoxideasync-std 运行时

chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", branch = "main"}

要使用 tokio 运行时,请添加 features = ["tokio-runtime"] 并设置 default-features = false 以禁用默认运行时(async-std

chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", features = ["tokio-runtime"], default-features = false, branch = "main"}

这种配置主要得益于所选择的 websocket crate:async-tungstenite

生成的代码

chromiumoxide_pdl crate 包含一个 PDL 解析器,这是对铬源树中 python 脚本 的 rust 重写,以及一个 Generator,它将解析的 PDL 文件转换为 rust 代码。 chromiumoxide_cdp crate 的唯一目的是在其 构建过程 中调用生成器并在编译 crate 之前 包含生成的输出。这种分离仅仅是因为生成的输出是约 60K 行的 rust 代码(不包括所有进程宏的展开)。所以请预期编译会花费一些时间。生成器可以独立配置和使用,请参阅 chromiumoxide_cdp/build.rs

每个 chrome pdl 域都放在自己的 rust 模块中,浏览器协议页面域的类型在 chromiumoxide_cdp::cdp::browser_protocol::page 中,js_protocol 的运行域在 chromiumoxide_cdp::cdp::js_protocol::runtime 中,等等。

vanilla.aslushnikov.com 是浏览 pdl 文件中定义的所有类型的极好资源。该网站以 Command 类型在 pdl 文件中定义的方式显示为 Methodchromiumoxid 保留 Command 命名约定。因此,对于在 pdl 中定义为命令类型(在 vanilla.aslushnikov.com 上标记为 Method)的所有内容,chromiumoxide 包含一个命令类型和一个指定的返回类型。每个命令都有一个具有构建器支持的 <命令名称>Params 类型(<命令名称>Params::builder())及其相应的返回类型:<命令名称>Returns。所有命令都共享 chromiumoxide_types::Command 特性的实现。所有事件都打包在一个单个枚举中(CdpEvent

Fetcher

默认情况下,chromiumoxide 将尝试在其运行的计算机上找到已安装的铬版本。对于某些平台,可以使用 fetcher 自动下载和安装。

由于 Cargo 的一个错误,功能目前有些混乱,一旦解决将会更改。根据您的运行时和 TLS 配置,您应该启用以下之一:

  • _fetcher-rustls-async-std
  • _fetcher-rusttls-tokio
  • _fetcher-native-async-std
  • _fetcher-native-tokio
use std::path::Path;

use futures::StreamExt;

use chromiumoxide::browser::{BrowserConfig};
use chromiumoxide::fetcher::{BrowserFetcher, BrowserFetcherOptions};

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    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()
        .chrome_executable(info.executable_path)
        .build()?,
}

已知问题

  • chromiumoxide_cdp 中为 PDL 文件生成的 rust 文件,当手动关闭实验类型支持时无法编译(export CDP_NO_EXPERIMENTAL=true)。这是因为 *.pdl 文件本身中使用的一些实验性 pdl 类型并未标记为实验性。

故障排除

问题:正在启动一个新的铬实例,但然后超时。

答案:检查您的铬语言设置是否设置为英语。 chromiumoxide 尝试从铬进程输出中解析调试端口,这仅限于英语。

许可证

许可以下之一:

参考

依赖项

~9–29MB
~444K SLoC