Rust 中的请求拦截

问题描述 投票:0回答:3

我正在尝试获取浏览器发送的每个请求并打印它。 我找到了一个 crate headless_chrome 并尝试使用它,但到目前为止还没有成功弄清楚如何使用它。如果您知道任何其他板条箱或如何用 Rust 制作它的方法,请告诉我。任何和所有的帮助将不胜感激。

这是我到目前为止的代码,我尝试启用请求侦听器,但它需要

Arc<dyn RequestInterceptor + Send + Sync>
并且到目前为止我无法弄清楚如何创建它,而且我没有通过它。我缺少对请求执行某些操作的代码。

编辑:我发现我需要返回一个RequestPausedDecision,但仍然不知道该怎么做

use std::sync::Arc;

use anyhow::Result;
use headless_chrome::browser::tab::RequestInterceptor;
use headless_chrome::browser::tab::Tab;
use headless_chrome::protocol::cdp::types::Event;
use headless_chrome::protocol::cdp::IndexedDB::RequestData;
use headless_chrome::protocol::cdp::Page;
use headless_chrome::Browser;

#[tokio::main]
async fn request_interceptor_function(mut url: String) -> Result<(), Box<dyn Error>> {
    let browser = Browser::default()?;

    let tab = browser.new_tab()?;

    tab.navigate_to(
        "https://animeheaven.ru/watch/the-ancient-magus-bride-season-2.55921?ep=183710",
    )?;
    println!("Navigated to website");
    // Arc<Transport>, SessionId, RequestPausedEvent
    const req_interceptor: Arc<dyn RequestInterceptor + Send + Sync> = Arc::new(
        |transport: Arc<transport::Transport>,
         session_id: SessionId,
         intercepted_req: RequestPausedEvent| {

        },
    );
    Ok(())
}


fn main() {
    let url = "https://www.example.com";
    request_interceptor_function(title.to_string());
}

这是感谢评论的编辑版本

use anyhow::Result;
use headless_chrome::browser::tab::RequestInterceptor;
use headless_chrome::browser::tab::RequestPausedDecision;
use headless_chrome::browser::transport::SessionId;
use headless_chrome::browser::transport::Transport;
use headless_chrome::protocol::cdp::Fetch::events::RequestPausedEvent;
use headless_chrome::Browser;
use std::error::Error;
use std::sync::Arc;

struct PrintingInterceptor {}

impl RequestInterceptor for PrintingInterceptor {
    fn intercept(
        &self,
        _transport: Arc<Transport>,
        _session_id: SessionId,
        event: RequestPausedEvent,
    ) -> RequestPausedDecision {
        let url = event.params.request.url.as_str();
        println!("{}", url);
        RequestPausedDecision::Continue(None)
    }
}

#[tokio::main]
async fn request_interceptor_function(url: &str) -> Result<(), Box<dyn Error>> {
    println!("Navigating to website");

    let browser = Browser::default()?;
    let tab = browser.new_tab()?;

    let request_interceptor: Arc<dyn RequestInterceptor + Send + Sync> =
        Arc::new(PrintingInterceptor {});

    tab.navigate_to(url)?;
    tab.wait_until_navigated()?;
    println!("Navigated to website");
    tab.enable_request_interception(request_interceptor)?;

    println!("Enabled request interception");

    Ok(())
}

fn main() {
    let url = "https://animeheaven.ru/watch/the-ancient-magus-bride-season-2.55921?ep=183710";
    let res = request_interceptor_function(url);
    println!("{:?}", res);
}

rust google-chrome-headless headless-browser
3个回答
0
投票

RequestInterceptor
是一个你可以实现的特质。您必须定义一个类型,实现该类型的特征,并将该类型的值放入
Arc

这样的东西应该有效。 (我没有编译过这段代码,所以可能会有一些小错误。)

let request_interceptor: Arc<dyn RequestInterceptor + Send + Sync> =
    Arc::new(PrintingInterceptor {});
struct PrintingInterceptor {}

impl RequestInterceptor for PrintingInterceptor {
    fn intercept(
        &self,
        transport: Arc<Transport>,
        session_id: SessionId,
        event: RequestPausedEvent
    ) -> RequestPausedDecision {
        let url = event.params.request.url.as_str();
        println!("{url}");
        RequestPausedDecision::Continue(None)
    }
}

如果您的拦截器需要额外的数据才能工作,请将其作为字段放在

struct
中。


0
投票

在弄乱这个包几天后(最初我也遇到了同样的问题,不幸的是我对 Rust 和 Chrome DevTools 协议没有任何经验),我发现你需要为 CDP 启用某些域(https://chromedevtools .github.io/devtools-protocol/tot/Fetch/#method-enable)从 WS 通道接收事件。

您需要在

enable_request_interception
之前添加此内容才能使您的拦截器工作:

tab.enable_fetch(None, None)?;

0
投票

我已经获得了请求的 URL 和 ID 等值,但我很难检索该请求的响应正文。你能帮我吗?

© www.soinside.com 2019 - 2024. All rights reserved.