Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Listen to network requests and get their Body "Fetch domain is not enabled" #256

Open
MisterSzled opened this issue Feb 7, 2025 · 1 comment

Comments

@MisterSzled
Copy link

I'm currently trying to listen to all the requests made by a page.

I've managed to get to a point where I can list all the requests but I'm failing to get their body.

My results typically look like:

Response received for request RequestId("9233.182"): https://en.wikipedia.org/static/images/project-logos/enwiki.png
Failed to get response body: Error -32000: Fetch domain is not enabled

This error:
Failed to get response body: Error -32000: Fetch domain is not enabled
is the problem as I need to be able to scrape some JSON and I'm not sure how to correct it.
I'm guessing it's an easy fix with some CDP command but I can't see it.
Any help would be really appreciated.

I've created a minimal example of what i've done so far here:

use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::handler::viewport::Viewport;
use futures::StreamExt;

use chromiumoxide::cdp::browser_protocol::network::EventResponseReceived;
use chromiumoxide::cdp::browser_protocol::fetch::GetResponseBodyParams;

#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let mut viewport = Viewport::default();
        viewport.width = 1920;
        viewport.height = 1200;
        let (mut browser, mut handler) = Browser::launch(
                BrowserConfig::builder()
                        .with_head()
                        .viewport(viewport)
                        .window_size(1920, 1200)
                        .build()?,
        )
        .await?;

        let handler_task = async_std::task::spawn(async move {
                while let Some(event) = handler.next().await {
                        if let Err(e) = event {
                                eprintln!("Handler error: {}", e);
                                break;
                        }
                }
        });

        let page = browser.new_page("https://en.wikipedia.org").await?;

        let mut network_events = page.event_listener::<EventResponseReceived>().await?;
        let network_task = async_std::task::spawn({
                let page = page.clone();
                async move {
                        while let Some(event) = network_events.next().await {
                                println!(
                                        "Response received for request {:?}: {}",
                                        event.request_id, event.response.url
                                );

                                let body = page
                                        .execute(GetResponseBodyParams::new(event.request_id.clone()))
                                        .await;
                                match body {
                                        Ok(response_body) => {
                                                println!(
                                                        "Response body (base64 encoded = {}): {}",
                                                        response_body.base64_encoded,
                                                        response_body.body
                                                );
                                        }
                                        Err(e) => eprintln!("Failed to get response body: {}", e),
                                }
                        }
                        Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
                }
        });

        page.find_element("input#searchInput")
                .await?
                .click()
                .await?
                .type_str("Rust programming language")
                .await?
                .press_key("Enter")
                .await?;

        // Wait for the navigation and then get the page content.
        let html = page.wait_for_navigation().await?.content().await?;
        println!("Page content length: {}", html.len());

        browser.close().await?;

        // Await the spawned tasks.
        network_task.await;
        handler_task.await;

        Ok(())
}
@MisterSzled
Copy link
Author

I've been tracking through the docs and have enabled .enable_request_intercept() in my browser builder now.

However when trying to listen to the events mentioned as:

let mut browser_auth_requests = browser.event_listener::<EventAuthRequired>().await?;
let auth_tasks = async_std::task::spawn({
        async move {
                while let Some(event) = browser_auth_requests.next().await {
                        println!(
                                "Response received for request {:?}",
                                event.request_id
                        );
                }
                Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
        }
});

I don't see any events.

I have tried attaching the listener to the page instead of the browser but I can't define a new page without a valid url and since I have .enable_request_intercept() enabled every request requires auth which I can't provide since the event listener isn't yet attached...

I tried a similar set of code from: #254 but I think it's the same problem I'm having here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant