Saltar al contenido principal

Requisitos previos

Configuración

Añade tu clave de API a appsettings.json:
{
  "Firecrawl": {
    "ApiKey": "fc-YOUR-API-KEY",
    "BaseUrl": "https://api.firecrawl.dev/v2"
  }
}
O bien usa variables de entorno / secretos de usuario:
export Firecrawl__ApiKey=fc-YOUR-API-KEY

Crear un servicio

Crea Services/FirecrawlService.cs:
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

public class FirecrawlService
{
    private readonly HttpClient _http;
    private readonly string _baseUrl;

    public FirecrawlService(IConfiguration config)
    {
        _baseUrl = config["Firecrawl:BaseUrl"] ?? "https://api.firecrawl.dev/v2";
        _http = new HttpClient();
        _http.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", config["Firecrawl:ApiKey"]);
    }

    public async Task<JsonDocument> SearchAsync(string query, int limit = 5)
    {
        var content = new StringContent(
            JsonSerializer.Serialize(new { query, limit }),
            Encoding.UTF8, "application/json");

        var response = await _http.PostAsync($"{_baseUrl}/search", content);
        response.EnsureSuccessStatusCode();
        return JsonDocument.Parse(await response.Content.ReadAsStringAsync());
    }

    public async Task<JsonDocument> ScrapeAsync(string url)
    {
        var content = new StringContent(
            JsonSerializer.Serialize(new { url }),
            Encoding.UTF8, "application/json");

        var response = await _http.PostAsync($"{_baseUrl}/scrape", content);
        response.EnsureSuccessStatusCode();
        return JsonDocument.Parse(await response.Content.ReadAsStringAsync());
    }

    public async Task<JsonDocument> InteractAsync(string url, string prompt, string? followUp = null)
    {
        // 1. Hacer scraping para abrir una sesión de navegador
        var scrapeContent = new StringContent(
            JsonSerializer.Serialize(new { url, formats = new[] { "markdown" } }),
            Encoding.UTF8, "application/json");

        var scrapeRes = await _http.PostAsync($"{_baseUrl}/scrape", scrapeContent);
        scrapeRes.EnsureSuccessStatusCode();
        var scrapeDoc = JsonDocument.Parse(await scrapeRes.Content.ReadAsStringAsync());
        var scrapeId = scrapeDoc.RootElement
            .GetProperty("data").GetProperty("metadata").GetProperty("scrapeId").GetString();

        // 2. Enviar el primer prompt
        var firstPrompt = new StringContent(
            JsonSerializer.Serialize(new { prompt }),
            Encoding.UTF8, "application/json");
        await _http.PostAsync($"{_baseUrl}/scrape/{scrapeId}/interact", firstPrompt);

        // 3. Enviar el prompt de seguimiento
        JsonDocument? result = null;
        if (followUp != null)
        {
            var followUpContent = new StringContent(
                JsonSerializer.Serialize(new { prompt = followUp }),
                Encoding.UTF8, "application/json");
            var followUpRes = await _http.PostAsync(
                $"{_baseUrl}/scrape/{scrapeId}/interact", followUpContent);
            followUpRes.EnsureSuccessStatusCode();
            result = JsonDocument.Parse(await followUpRes.Content.ReadAsStringAsync());
        }

        // 4. Cerrar la sesión
        await _http.DeleteAsync($"{_baseUrl}/scrape/{scrapeId}/interact");

        return result ?? scrapeDoc;
    }
}

Registrar y usar

En Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<FirecrawlService>();

var app = builder.Build();

app.MapPost("/api/search", async (FirecrawlService firecrawl, SearchRequest req) =>
{
    var result = await firecrawl.SearchAsync(req.Query, req.Limit);
    return Results.Ok(result.RootElement);
});

app.MapPost("/api/scrape", async (FirecrawlService firecrawl, ScrapeRequest req) =>
{
    var result = await firecrawl.ScrapeAsync(req.Url);
    return Results.Ok(result.RootElement);
});

app.MapPost("/api/interact", async (FirecrawlService firecrawl, InteractRequest req) =>
{
    var result = await firecrawl.InteractAsync(req.Url, req.Prompt, req.FollowUp);
    return Results.Ok(result.RootElement);
});

app.Run();

record SearchRequest(string Query, int Limit = 5);
record ScrapeRequest(string Url);
record InteractRequest(string Url, string Prompt, string? FollowUp = null);

Ejecútalo

dotnet run

Pruébalo

# Buscar en la web
curl -X POST http://localhost:5000/api/search \
  -H "Content-Type: application/json" \
  -d '{"query": "firecrawl web scraping"}'

# Hacer scraping de una página
curl -X POST http://localhost:5000/api/scrape \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'

# Interactuar con una página
curl -X POST http://localhost:5000/api/interact \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.amazon.com", "prompt": "Search for iPhone 16 Pro Max", "followUp": "Click on the first result and tell me the price"}'

Próximos pasos

Documentación de búsqueda

Buscar en la web y obtener el contenido completo de la página

Documentación de scraping

Todas las opciones de scraping, incluidos formatos, acciones y proxies

Documentación de interacción

Haz clic, completa formularios y extrae contenido dinámico

Referencia de la API

Documentación completa de la API REST