typestar

crawler.go en Go

Descarga varias URL de forma concurrente y reporta cada resultado.

// Descarga varias URLs de forma concurrente y reporta estado y tamaño.
package main

import (
    "fmt"
    "io"
    "net/http"
    "sync"
    "time"
)

type result struct {
    url    string
    status int
    size   int
    err    error
}

func fetch(url string, client *http.Client) result {
    resp, err := client.Get(url)
    if err != nil {
        return result{url: url, err: err}
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    return result{
        url:    url,
        status: resp.StatusCode,
        size:   len(body),
        err:    err,
    }
}

func main() {
    urls := []string{
        "https://example.com",
        "https://example.org",
        "https://example.net",
    }
    client := &http.Client{Timeout: 10 * time.Second}

    results := make(chan result, len(urls))
    var wg sync.WaitGroup
    start := time.Now()

    for _, url := range urls {
        wg.Add(1)
        go func(u string) {
            defer wg.Done()
            results <- fetch(u, client)
        }(url)
    }

    wg.Wait()
    close(results)

    for r := range results {
        if r.err != nil {
            fmt.Printf("%-24s error: %v\n", r.url, r.err)
            continue
        }
        fmt.Printf("%-24s %d  %d bytes\n", r.url, r.status, r.size)
    }
    elapsed := time.Since(start).Round(time.Millisecond)
    fmt.Printf("fetched %d urls in %s\n", len(urls), elapsed)
}

Cómo funciona

  1. Una goroutine por URL envía a un canal con búfer.
  2. Un struct result lleva el estado, el tamaño o el error.
  3. WaitGroup y luego close dejan que el lector lo drene.

Palabras clave y builtins usados aquí

El intento, en números

Líneas
67
Caracteres a escribir
1139
Tokens
294
Ritmo de tres estrellas
110 tpm

Al ritmo de tres estrellas de 110 tokens por minuto, este intento toma unos 160 segundos.

Escribe este fragmento

Paso 1 de 2 en Bis; paso 24 de 25 en Concurrencia.

← Anterior Siguiente →