2个稳定版本

1.0.6 2023年5月4日

#7#puppeteer

每月24次下载

MIT许可协议

235KB
6K SLoC

无头Chrome

Build Status Crate API Discord channel

通过DevTools协议控制无头Chrome或Chromium的高级API。它是Chrome DevTools团队维护的Node库Puppeteer的Rust等效版本。

它并非与Puppeteer完全功能兼容,但提供了足够的功能来满足大多数浏览器测试/网络爬虫用例,还有一些“高级”功能,例如

快速开始

use std::error::Error;

use headless_chrome::Browser;
use headless_chrome::protocol::cdp::Page;

fn browse_wikipedia() -> Result<(), Box<dyn Error>> {
    let browser = Browser::default()?;

    let tab = browser.new_tab()?;

    /// Navigate to wikipedia
    tab.navigate_to("https://www.wikipedia.org")?;

    /// Wait for network/javascript/dom to make the search-box available
    /// and click it.
    tab.wait_for_element("input#searchInput")?.click()?;

    /// Type in a query and press `Enter`
    tab.type_str("WebKit")?.press_key("Enter")?;

    /// We should end up on the WebKit-page once navigated
    let elem = tab.wait_for_element("#firstHeading")?;
    assert!(tab.get_url().ends_with("WebKit"));

    /// Take a screenshot of the entire browser window
    let _jpeg_data = tab.capture_screenshot(
        Page::CaptureScreenshotFormatOption::Jpeg,
        None,
        None,
        true)?;

    /// Take a screenshot of just the WebKit-Infobox
    let _png_data = tab
        .wait_for_element("#mw-content-text > div > table.infobox.vevent")?
        .capture_screenshot(Page::CaptureScreenshotFormatOption::Png)?;

    // Run JavaScript in the page
    let remote_object = elem.call_js_fn(r#"
        function getIdTwice () {
            // `this` is always the element that you called `call_js_fn` on
            const id = this.id;
            return id + id;
        }
    "#, vec![], false)?;
    match remote_object.value {
        Some(returned_string) => {
            dbg!(&returned_string);
            assert_eq!(returned_string, "firstHeadingfirstHeading".to_string());
        }
        _ => unreachable!()
    };

    Ok(())
}

自动获取chrome二进制文件

[dependencies]
headless_chrome = {git = "https://github.com/atroche/rust-headless-chrome", features = ["fetch"]}

更多示例,请参阅 tests/simple.rsexamples

在运行示例之前。请确保在您的Cargo项目中添加 failure 包依赖项 Cargo.toml

它不能做什么?

Chrome DevTools Protocol 非常庞大。目前,Puppeteer支持的特性比我们多。一些缺失的功能包括

  • 处理框架
  • 处理文件选择器/选择器交互
  • 触摸屏触摸
  • 模拟不同的网络条件(DevTools可以改变延迟、吞吐量、离线状态、“连接类型”)
  • 查看网络请求的时间信息
  • 读取SSL证书
  • 重放XHR
  • HTTP基本认证
  • 检查 EventSource(即服务器发送事件或SSEs)
  • WebSocket检查

如果您有兴趣添加这些功能之一,但需要一些关于如何开始的建议,请通过创建问题或发送电子邮件到 alistair@sunburnt.country

  • fantoccini 使用 WebDriver,因此它可以与除 Chrome 以外的浏览器一起使用。它还是异步的,基于 Tokio,与 headless_chrome 不同,后者有一个同步 API,仅使用普通的线程实现。Fantoccini 的时间更长,而且经过更多实战测试。它不支持 Chrome DevTools 特定的功能,如 JS Coverage。

测试

在运行 cargo test 之前,设置以下环境变量以获取调试输出:

RUST_BACKTRACE=1 RUST_LOG=headless_chrome=trace

版本号

从 v0.2.0 版本开始,我们尝试严格遵循 SemVar。

故障排除

如果您遇到与超时相关的错误,您可能需要在内核中或作为 setuid 沙盒启用沙盒。Puppeteer 关于如何做到这一点有一些信息 在此处

默认情况下,headless_chrome 将下载一个兼容版本的 chrome 到 XDG_DATA_HOME(或 Windows/Mac 上的等效项)。此行为可以可选地关闭,您可以通过禁用 Cargo.toml 中的默认功能来使用系统版本的 chrome(假设您已安装 chrome)。

[dependencies.headless_chrome]
default-features = false

贡献

欢迎拉取请求和问题,即使是经验报告也行。如果您发现任何令人沮丧或困惑的地方,请告诉我!

依赖关系

~7–22MB
~359K SLoC