我正在尝试获取浏览器发送的每个请求并打印它。 我找到了一个 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);
}
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
中。
在弄乱这个包几天后(最初我也遇到了同样的问题,不幸的是我对 Rust 和 Chrome DevTools 协议没有任何经验),我发现你需要为 CDP 启用某些域(https://chromedevtools .github.io/devtools-protocol/tot/Fetch/#method-enable)从 WS 通道接收事件。
您需要在
enable_request_interception
之前添加此内容才能使您的拦截器工作:
tab.enable_fetch(None, None)?;
我已经获得了请求的 URL 和 ID 等值,但我很难检索该请求的响应正文。你能帮我吗?