Skip to content
Firecrawl Docs
Firecrawl Docs
Oficial

Rust

O SDK do Firecrawl para Rust é um wrapper da API do Firecrawl para ajudar você a converter sites em markdown com facilidade.

O SDK oficial do Firecrawl para Rust é mantido no monorepo do Firecrawl em apps/rust-sdk.

Para instalar o SDK do Firecrawl para Rust, adicione a dependência do crates.io:

[dependencies]
firecrawl = "2"
tokio = { version = "1", features = ["full"] }
serde_json = "1"

Ou instale com o Cargo:

cargo add firecrawl
cargo add tokio --features full
cargo add serde_json
Requer Rust 1.70 ou superior.
  1. Obtenha uma chave de API em firecrawl.dev
  2. Defina a chave de API como uma variável de ambiente chamada FIRECRAWL_API_KEY ou passe-a diretamente para Client::new(...)

Faça scraping de uma página e imprima seu markdown:

use firecrawl::{Client, ScrapeOptions, Format};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("fc-YOUR-API-KEY")?;

    let doc = client.scrape(
        "https://firecrawl.dev",
        ScrapeOptions {
            formats: Some(vec![Format::Markdown]),
            ..Default::default()
        },
    ).await?;

    println!("{}", doc.markdown.unwrap_or_default());
    Ok(())
}

As seções abaixo abordam o rastreamento, o mapeamento, a busca e outros métodos do SDK.

Para fazer scraping de uma única URL, use o método scrape.

use firecrawl::{Client, ScrapeOptions, Format};

let doc = client.scrape(
    "https://firecrawl.dev",
    ScrapeOptions {
        formats: Some(vec![Format::Markdown, Format::Html]),
        only_main_content: Some(true),
        wait_for: Some(5000),
        ..Default::default()
    },
).await?;

println!("{}", doc.markdown.unwrap_or_default());
if let Some(meta) = &doc.metadata {
    println!("{:?}", meta.title);
}

Extraia dados JSON estruturados usando scrape_with_schema:

use firecrawl::Client;
use serde_json::json;

let schema = json!({
    "type": "object",
    "properties": {
        "name": { "type": "string" },
        "price": { "type": "number" }
    }
});

let data = client.scrape_with_schema(
    "https://example.com/product",
    schema,
    Some("Extract the product name and price"),
).await?;

println!("{}", serde_json::to_string_pretty(&data)?);

Ou configure a extração JSON diretamente via ScrapeOptions:

use firecrawl::{Client, ScrapeOptions, Format, JsonOptions};
use serde_json::json;

let doc = client.scrape(
    "https://example.com/product",
    ScrapeOptions {
        formats: Some(vec![Format::Json]),
        json_options: Some(JsonOptions {
            schema: Some(json!({
                "type": "object",
                "properties": {
                    "name": { "type": "string" },
                    "price": { "type": "number" }
                }
            })),
            prompt: Some("Extract the product name and price".to_string()),
            ..Default::default()
        }),
        ..Default::default()
    },
).await?;

println!("{:?}", doc.json);

Use parse para enviar um arquivo local (.html, .htm, .pdf, .docx, .doc, .odt, .rtf, .xlsx, .xls) como multipart/form-data para /v2/parse. O endpoint retorna um Document com os formatos solicitados.

ParseOptions omite intencionalmente campos exclusivos de scraping que /v2/parse rejeita (como actions, waitFor, location, mobile, screenshot, branding e changeTracking).

Crie um ParseFile a partir de bytes em memória ou diretamente de um caminho de arquivo:

use firecrawl::{Client, ParseFile, ParseFormat, ParseOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("fc-YOUR-API-KEY")?;

    let file = ParseFile::from_bytes(
        "upload.html",
        b"<!DOCTYPE html><html><body><h1>Rust Parse</h1></body></html>".to_vec(),
    )
    .with_content_type("text/html");

    let options = ParseOptions {
        formats: Some(vec![ParseFormat::Markdown, ParseFormat::Html]),
        only_main_content: Some(true),
        ..Default::default()
    };

    let doc = client.parse(file, Some(options)).await?;
    println!("{}", doc.markdown.unwrap_or_default());
    Ok(())
}

Ou leia o arquivo do disco local e omita as opções:

use firecrawl::{Client, ParseFile};

let client = Client::new("fc-YOUR-API-KEY")?;
let file = ParseFile::from_path("./report.pdf")?;

let doc = client.parse(file, None).await?;
println!("{}", doc.markdown.unwrap_or_default());
ConstrutorDescrição
ParseFile::from_bytes(filename, bytes)Cria a partir de um nome de arquivo e bytes na memória
ParseFile::from_path(path)Lê os bytes do disco e deriva o nome do arquivo
.with_content_type(content_type)Adiciona uma indicação de tipo MIME (por ex. text/html, application/pdf)

Campos compatíveis (todos opcionais, em camelCase na transmissão):

  • formats: Vec<ParseFormat> — qualquer um dos seguintes: Markdown, Html, RawHtml, Links, Images, Summary, Json, Attributes
  • only_main_content: bool
  • include_tags: Vec<String> / exclude_tags: Vec<String>
  • headers: HashMap<String, String>
  • timeout: u32 (ms)
  • parsers: Vec<ParserConfig> (ex.: configuração do parser de PDF)
  • skip_tls_verification: bool
  • remove_base64_images: bool
  • fast_mode: bool
  • block_ads: bool
  • proxy: ParseProxyType (Basic ou Auto)
  • json_options: JsonOptions
  • attribute_selectors: Vec<AttributeSelector>
  • zero_data_retention: bool
  • integration: String, origin: String, use_mock: String

Para rastrear um site e aguardar a conclusão, use crawl.

use firecrawl::{Client, CrawlOptions, ScrapeOptions, Format};

let job = client.crawl(
    "https://firecrawl.dev",
    CrawlOptions {
        limit: Some(50),
        max_discovery_depth: Some(3),
        scrape_options: Some(ScrapeOptions {
            formats: Some(vec![Format::Markdown]),
            ..Default::default()
        }),
        ..Default::default()
    },
).await?;

println!("Status: {:?}", job.status);
println!("Progress: {}/{}", job.completed, job.total);

for page in &job.data {
    if let Some(meta) = &page.metadata {
        println!("{:?}", meta.source_url);
    }
}

Inicie um job sem aguardar usando start_crawl.

use firecrawl::{Client, CrawlOptions};

let start = client.start_crawl(
    "https://firecrawl.dev",
    CrawlOptions {
        limit: Some(100),
        ..Default::default()
    },
).await?;

println!("Job ID: {}", start.id);

Verifique o andamento do rastreamento com get_crawl_status.

let status = client.get_crawl_status(&start.id).await?;
println!("Status: {:?}", status.status);
println!("Progress: {}/{}", status.completed, status.total);

Cancele um rastreamento em execução com cancel_crawl.

let result = client.cancel_crawl(&start.id).await?;
println!("{:?}", result);

Recupere os erros de um job de rastreamento com get_crawl_errors.

let errors = client.get_crawl_errors(&start.id).await?;
println!("{:?}", errors);

Encontre links em um site com map.

use firecrawl::{Client, MapOptions};

let response = client.map(
    "https://firecrawl.dev",
    MapOptions {
        limit: Some(100),
        search: Some("blog".to_string()),
        ..Default::default()
    },
).await?;

for link in &response.links {
    println!("{} - {}", link.url, link.title.as_deref().unwrap_or(""));
}

Para um resultado mais simples, com apenas URLs, use map_urls:

let urls = client.map_urls("https://firecrawl.dev", None).await?;
for url in &urls {
    println!("{}", url);
}

Faça uma busca com configurações opcionais usando search.

use firecrawl::{Client, SearchOptions};

let results = client.search(
    "firecrawl web scraping",
    SearchOptions {
        limit: Some(10),
        ..Default::default()
    },
).await?;

if let Some(web) = results.data.web {
    for item in web {
        match item {
            firecrawl::SearchResultOrDocument::WebResult(r) => {
                println!("{} - {}", r.url, r.title.unwrap_or_default());
            }
            firecrawl::SearchResultOrDocument::Document(d) => {
                println!("{}", d.markdown.unwrap_or_default());
            }
        }
    }
}

Para um método auxiliar que retorna documentos extraídos diretamente:

let docs = client.search_and_scrape("firecrawl web scraping", 5).await?;
for doc in &docs {
    println!("{}", doc.markdown.as_deref().unwrap_or(""));
}

Faça scraping de várias URLs em paralelo com batch_scrape.

use firecrawl::{Client, BatchScrapeOptions, ScrapeOptions, Format};

let urls = vec![
    "https://firecrawl.dev".to_string(),
    "https://firecrawl.dev/blog".to_string(),
];

let job = client.batch_scrape(
    urls,
    BatchScrapeOptions {
        options: Some(ScrapeOptions {
            formats: Some(vec![Format::Markdown]),
            ..Default::default()
        }),
        ..Default::default()
    },
).await?;

for doc in &job.data {
    println!("{}", doc.markdown.as_deref().unwrap_or(""));
}

Execute um agente com IA usando agent.

use firecrawl::{Client, AgentOptions};

let result = client.agent(
    AgentOptions {
        prompt: "Find the pricing plans for Firecrawl and compare them".to_string(),
        ..Default::default()
    },
).await?;

println!("{:?}", result.data);

Com um schema JSON para resultado estruturado:

use firecrawl::{Client, AgentOptions, AgentModel};
use serde::Deserialize;
use serde_json::json;

#[derive(Debug, Deserialize)]
struct PricingPlan {
    name: String,
    price: String,
}

#[derive(Debug, Deserialize)]
struct PricingData {
    plans: Vec<PricingPlan>,
}

let schema = json!({
    "type": "object",
    "properties": {
        "plans": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "name": { "type": "string" },
                    "price": { "type": "string" }
                }
            }
        }
    }
});

let result: Option<PricingData> = client.agent_with_schema(
    vec!["https://firecrawl.dev".to_string()],
    "Extract pricing plan details",
    schema,
).await?;

if let Some(data) = result {
    for plan in &data.plans {
        println!("{}: {}", plan.name, plan.price);
    }
}

Use um ID do job de scraping para executar código adicional no navegador no mesmo contexto:

  • interact(...) executa código ou prompts na sessão do navegador vinculada ao scraping.
  • stop_interaction(...) encerra a sessão interativa quando terminar.
use firecrawl::{Client, ScrapeExecuteOptions, ScrapeExecuteLanguage};

let scrape_job_id = "550e8400-e29b-41d4-a716-446655440000";

// Executar código na sessão do navegador
let run = client.interact(
    scrape_job_id,
    ScrapeExecuteOptions {
        code: Some("console.log(await page.title())".to_string()),
        language: Some(ScrapeExecuteLanguage::Node),
        timeout: Some(60),
        ..Default::default()
    },
).await?;

println!("{:?}", run.stdout);

// Ou usar um prompt em linguagem natural
let run = client.interact(
    scrape_job_id,
    ScrapeExecuteOptions {
        prompt: Some("Click the pricing tab and summarize the plans".to_string()),
        ..Default::default()
    },
).await?;

// Encerrar a sessão quando concluído
client.stop_interaction(scrape_job_id).await?;

Client::new(...) e Client::new_selfhosted(...) criam o cliente.

OpçãoDescrição
Client::new(api_key)Cria um cliente para o serviço em nuvem do Firecrawl (https://api.firecrawl.dev)
Client::new_selfhosted(api_url, api_key)Cria um cliente para uma instância auto-hospedada do Firecrawl
use firecrawl::Client;

// Serviço em nuvem
let client = Client::new("fc-your-api-key")?;

// Auto-hospedado
let client = Client::new_selfhosted(
    "http://localhost:3002",
    Some("fc-your-api-key"),
)?;

// Auto-hospedado sem autenticação
let client = Client::new_selfhosted(
    "http://localhost:3002",
    None::<&str>,
)?;

Defina a variável de ambiente FIRECRAWL_API_KEY em vez de informar a chave diretamente:

export FIRECRAWL_API_KEY=fc-YOUR-API-KEY
let api_key = std::env::var("FIRECRAWL_API_KEY")
    .expect("FIRECRAWL_API_KEY must be set");
let client = Client::new(api_key)?;

Os métodos síncronos (crawl, batch_scrape, agent) consultam o status até a conclusão. Você pode personalizar o intervalo de consulta por meio da struct options:

use firecrawl::CrawlOptions;

let options = CrawlOptions {
    limit: Some(50),
    poll_interval: Some(3000), // Consultar a cada 3 segundos (padrão: 2000ms)
    ..Default::default()
};

O SDK usa o enum FirecrawlError, que implementa Error, Debug e Display. Todos os métodos retornam Result<T, FirecrawlError>.

use firecrawl::{Client, FirecrawlError};

match client.scrape("https://example.com", None).await {
    Ok(doc) => println!("{}", doc.markdown.unwrap_or_default()),
    Err(FirecrawlError::HttpRequestFailed(action, status, msg)) => {
        eprintln!("HTTP {}: {} ({})", status, msg, action);
    }
    Err(FirecrawlError::APIError(action, api_err)) => {
        eprintln!("API error ({}): {}", action, api_err.error);
    }
    Err(FirecrawlError::JobFailed(msg)) => {
        eprintln!("Job failed: {}", msg);
    }
    Err(FirecrawlError::Misuse(msg)) => {
        eprintln!("SDK misuse: {}", msg);
    }
    Err(e) => eprintln!("Error: {}", e),
}

Você é um agente de IA que precisa de uma chave de API do Firecrawl? Veja firecrawl.dev/agent-onboarding/SKILL.md para instruções de onboarding automatizado.

Was this page helpful?Suggest editsRaise issue