pu369com

Rust 使用 Headless Chrome 入门指南

1 创建 Rust 项目

cargo new chrome_demo

2 在 Cargo.toml 中添加所需依赖

cd headless_chrome
cargo add headless_chrome tokio serde_json anyhow 

3 创建浏览器实例,并访问 https://example.com

use headless_chrome::{Browser, LaunchOptions};
use anyhow::Result;

fn main() -> Result<()> {
    // 启动浏览器
    let browser = Browser::new(
        LaunchOptions::default_builder()
            .headless(true)  // 设置为无头模式
            .sandbox(false)  // 禁用沙箱
            .build()
            .expect("Could not find chrome-executable"),
    )?;

    // 创建新标签页
    let tab = browser.new_tab()?;

    // 导航到网页
    tab.navigate_to("https://example.com")?;

    // 等待页面加载
    tab.wait_until_navigated()?;

    println!("页面标题: {}", tab.get_title()?);

    Ok(())
}

复杂些例子:

use headless_chrome::{Browser, LaunchOptions};
use std::error::Error;
use anyhow::{Result, Context};
use std::time::Duration;

async fn create_browser() -> Result<Browser, Box<dyn Error>> {
        let browser = Browser::new(
        LaunchOptions::default_builder()
            .headless(false)
            .window_size(Some((1920, 1080)))            
            .build()
            .context("无法创建浏览器实例")?,
    )?;
    Ok(browser)
}

async fn login(browser: &Browser) -> Result<std::sync::Arc<headless_chrome::Tab>, Box<dyn Error>> {
    let tab = browser.new_tab()?;
    // 导航到登录页面
    println!("正在导航到登录页面...");
    tab.navigate_to("http://192.168.13.3:8000/")
        .context("导航到登录页面失败")?;
    
    tab.wait_until_navigated().context("等待登录页面加载失败")?;
    
    // 等待登录表单加载
    println!("等待登录表单...");
    let username_selector = "input[id='username']";
    let username_element = tab.wait_for_element(username_selector)
        .context("找不到用户名输入框")?;
    
    // 填写用户名
    println!("填写用户名...");
    username_element.click().context("点击用户名输入框失败")?;
    username_element.type_into("你的用户名").context("输入用户名失败")?;
    
    // 填写密码
    println!("填写密码...");
    let password_selector = "input[id='password']";
    let password_element = tab.wait_for_element(password_selector)?;
    password_element.click().context("点击密码输入框失败")?;
    password_element.type_into("你的密码").context("输入密码失败")?;
    
    // 点击登录按钮
    println!("点击登录按钮...");
    let login_button_selector = "button[type='button']";
    let login_button = tab.wait_for_element(login_button_selector)?;
    
    // 点击登录按钮并等待导航
    login_button.click().context("点击登录按钮失败")?;
    tab.wait_until_navigated()?;
    
    // 添加额外等待确保页面完全加载
    std::thread::sleep(Duration::from_secs(2));
    Ok(tab)
}

async fn logout(tab: &std::sync::Arc<headless_chrome::Tab>) -> Result<(), Box<dyn Error>> {
    println!("准备注销,是否继续?(y/n)");
    
    let mut input = String::new();
    std::io::stdin().read_line(&mut input)?;
    
    if input.trim().eq_ignore_ascii_case("y") {          
        // 等待并点击用户logo
        println!("正在点击用户logo...");
        let logo_selector = "img[fieldid='userlogo_img']";
        let logo = tab.wait_for_element(logo_selector)
            .context("找不到用户logo元素")?;
        logo.click().context("点击用户logo失败")?;

        // 等待并点击注销按钮
        println!("正在点击注销按钮...");
        let logout_selector = "div.exitDiv";
        let logout_button = tab.wait_for_element(logout_selector)
            .context("找不到注销按钮")?;
        logout_button.click().context("点击注销按钮失败")?;
        
        // 等待并点击确认按钮
        println!("正在点击确认按钮...");
        let confirm_selector = "button.u-button.nc-button-wrapper.button-primary";
        let confirm_button = tab.wait_for_element(confirm_selector)
            .context("找不到确认按钮")?;
        confirm_button.click().context("点击确认按钮失败")?;
        tab.wait_until_navigated()?;
        
        Ok(())
    } else {
        println!("已取消跳转");
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let browser = create_browser().await?;
    
    println!("Logging in to ...");
    let tab = login(&browser).await?;
    
    println!("Logging out to ...");
    logout(&tab).await?;
    
    Ok(())
}

cargo.toml

[package]
name = "chrome_demo1"
version = "0.1.0"
edition = "2021"

[dependencies]
headless_chrome = "1.0.0"
tokio = { version = "1.0", features = ["full"] }
anyhow = "1.0"

 

更多用法见参考原文

附:csdn不登录无法复制解决办法
1.在csdn界面按下F12
2.在Console界面输入以下两段代码内容

Array.from(document.querySelectorAll("code")).map(a=>{a.style="user-select:text;"})
$("#content_views").off("copy")

就可以不用登录就能复制代码了!
如果在csdn的Console界面不能复制代码需要手动输入以下内容
allow pasting
就Ok了!

 

参考:https://blog.csdn.net/will_csdn_go/article/details/149248503?spm=1001.2014.3001.5502

https://zhuanlan.zhihu.com/p/14412125992

posted on 2025-07-20 11:40  pu369com  阅读(89)  评论(0)    收藏  举报

导航