Perché utilizzare i proxy in Go?
Go è diventato il linguaggio di scelta per strumenti di rete ad alte prestazioni, raschietti web e client API. Le sue goroutine leggere, i primitivi concurrency incorporati, e una battaglia tested net/http libreria standard lo rendono ideale per applicazioni proxy-powered che hanno bisogno di gestire migliaia di richieste concorrenti.
Se stai costruendo un web scraping tubazione, monitoraggio Classifiche SERP, o la raccolta di dati di prezzi competitivi, il routing dei vostri clienti Go HTTP attraverso i proxy consente di ruotare gli indirizzi IP, bypassare le geo-restrizioni, ed evitare limiti di velocità in scala.
In questa guida, imparerai come configurare proxies in Go utilizzando sia la libreria standard che la ProxyHat Go SDK. Ogni snippet di codice è copy-paste-ready in modo da poter iniziare a raschiare in pochi minuti.
Installazione
ProxyHat Go SDK
Il modo più veloce per iniziare è con il SDK ufficiale. Gestisce l'autenticazione, la rotazione, la geo-targeting e si ritira dalla casella.
go get github.com/ProxyHatCom/go-sdk@latestSolo biblioteca standard
Se preferite zero dipendenze, Go's net/http e net/url i pacchetti sono tutto ciò di cui hai bisogno. Nessuna installazione supplementare richiesta.
Autenticazione e configurazione di base
ProxyHat utilizza l'autenticazione password-password sul endpoint proxy. Troverai le tue credenziali nel cruscotto ProxyHat. Un tipico URL proxy sembra questo:
http://USERNAME:PASSWORD@gate.proxyhat.com:8080Tenere le credenziali fuori dal codice sorgente. Utilizzare variabili di ambiente o .env file:
export PROXYHAT_USER="your_username"
export PROXYHAT_PASS="your_password"GET semplice Richiesta con Proxy
Ecco l'approccio minimo utilizzando solo la libreria standard:
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
)
func main() {
proxyURL, err := url.Parse(fmt.Sprintf(
"http://%s:%s@gate.proxyhat.com:8080",
os.Getenv("PROXYHAT_USER"),
os.Getenv("PROXYHAT_PASS"),
))
if err != nil {
log.Fatal(err)
}
client := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
},
}
resp, err := client.Get("https://httpbin.org/ip")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}Eseguilo e vedrai un indirizzo IP residenziale invece che tuo. Ogni richiesta è indirizzata attraverso ProxyHat's delega residenziale piscina.
Utilizzo di diversi tipi di proxy
ProxyHat supporta tre tipi di proxy, ciascuno adatto a diversi carichi di lavoro. Selezioni il tipo tramite la porta del proxy o una bandiera del nome utente:
| Tipo | Porto | Migliore per | Lattice di Avg |
|---|---|---|---|
| Residenziale | 8.000 | Raschiamento web, verifica ad | - 800 m. |
| Datacenter | 8010 | Richieste di massa ad alta velocità | - 200 m. |
| Mobile | 8020 | Social media, test app | - 1200 m. |
Per un confronto più profondo di quando usare ogni tipo, vedere la nostra guida su residenziale vs datacenter vs proxy mobili.
// Switch proxy type by changing the port
residentialProxy := "http://user:pass@gate.proxyhat.com:8080"
datacenterProxy := "http://user:pass@gate.proxyhat.com:8080"
mobileProxy := "http://user:pass@gate.proxyhat.com:8080"Avvicinamento manuale: Vai alla rete/http con configurazione proxy
Per il controllo completo, configurare il http.Transport direttamente. Questo consente di sintonizzare la connessione pooling, impostazioni TLS e timeout:
package main
import (
"crypto/tls"
"net/http"
"net/url"
"time"
)
func newProxyClient(proxyAddr string) (*http.Client, error) {
proxyURL, err := url.Parse(proxyAddr)
if err != nil {
return nil, err
}
transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
TLSClientConfig: &tls.Config{MinVersion: tls.VersionTLS12},
}
client := &http.Client{
Transport: transport,
Timeout: 30 * time.Second,
}
return client, nil
}Approccio consigliato: ProxyHat Go SDK
The ProxyHat Go SDK avvolge tutta la caldaia in una API pulita. Gestisce la connessione pooling, i retries automatici, la gestione delle sessioni e la geo-targeting per voi.
package main
import (
"context"
"fmt"
"log"
proxyhat "github.com/ProxyHatCom/go-sdk"
)
func main() {
client, err := proxyhat.NewClient(proxyhat.Config{
Username: "your_username",
Password: "your_password",
ProxyType: proxyhat.Residential,
})
if err != nil {
log.Fatal(err)
}
defer client.Close()
resp, err := client.Get(context.Background(), "https://httpbin.org/ip")
if err != nil {
log.Fatal(err)
}
fmt.Println("Status:", resp.StatusCode)
fmt.Println("Body:", string(resp.Body))
}L'SDK restituisce una risposta strutturata, gestisce la decompressione, e recupera automaticamente i guasti transitori. Controllare il Documentazione API per il riferimento completo metodo.
Rotating vs Sticky Sessions
ProxyHat supporta due modalità di sessione:
- Ruotare (default) — ogni richiesta riceve un nuovo IP. Ideale per grandi dimensioni web scraping.
- Sticky — lo stesso IP è tenuto per una durata configurabile (fino a 30 minuti). Utile per flussi multi-step come sequenze di login o crawls impaginati.
Sessioni di rotazione (SDK)
client, _ := proxyhat.NewClient(proxyhat.Config{
Username: "your_username",
Password: "your_password",
ProxyType: proxyhat.Residential,
// Rotating is the default — no extra config needed
})
// Each call uses a different IP
for i := 0; i < 5; i++ {
resp, _ := client.Get(context.Background(), "https://httpbin.org/ip")
fmt.Printf("Request %d: %s\n", i+1, string(resp.Body))
}Sessioni appiccicose (SDK)
session, _ := client.NewSession(proxyhat.SessionConfig{
Duration: 10 * time.Minute,
})
// All requests through this session use the same IP
resp1, _ := session.Get(context.Background(), "https://example.com/login")
resp2, _ := session.Post(context.Background(), "https://example.com/dashboard", payload)Sessioni appiccicose (manuali)
// Append session ID to the username
// Format: USERNAME-sid-SESSIONID
proxyURL := "http://user-sid-abc123:pass@gate.proxyhat.com:8080"Richieste Geo-Targeted
Hai bisogno di IP da un paese specifico? Supporti ProxyHat 190+ sedi. Passare il codice paese tramite SDK o come bandiera del nome utente:
// SDK approach
client, _ := proxyhat.NewClient(proxyhat.Config{
Username: "your_username",
Password: "your_password",
ProxyType: proxyhat.Residential,
Country: "US", // ISO 3166-1 alpha-2
State: "CA", // optional: state/region
City: "LA", // optional: city
})
resp, _ := client.Get(context.Background(), "https://httpbin.org/ip")
fmt.Println(string(resp.Body)) // US-based IP// Manual approach — append country to username
// Format: USERNAME-country-US
proxyURL := "http://user-country-US:pass@gate.proxyhat.com:8080"Il geo-targeting è essenziale per la localizzazione monitoraggio SERP, controlli sui prezzi regionali e test sulla disponibilità dei contenuti.
Gestione degli errori e Retries
Le richieste di rete tramite proxy possono fallire per motivi transitori: reimpostazioni di connessione, timeout o blocchi temporanei. Robusta gestione degli errori è fondamentale per i raschiatori di produzione.
Ripiani integrati SDK
client, _ := proxyhat.NewClient(proxyhat.Config{
Username: "your_username",
Password: "your_password",
ProxyType: proxyhat.Residential,
MaxRetries: 3,
RetryDelay: 2 * time.Second,
})Rettifica manuale con backoff esponenziale
package main
import (
"fmt"
"math"
"net/http"
"time"
)
func fetchWithRetry(client *http.Client, url string, maxRetries int) (*http.Response, error) {
var lastErr error
for attempt := 0; attempt <= maxRetries; attempt++ {
resp, err := client.Get(url)
if err == nil && resp.StatusCode < 500 {
return resp, nil
}
if err != nil {
lastErr = err
} else {
lastErr = fmt.Errorf("HTTP %d", resp.StatusCode)
resp.Body.Close()
}
backoff := time.Duration(math.Pow(2, float64(attempt))) * time.Second
time.Sleep(backoff)
}
return nil, fmt.Errorf("all %d retries failed: %w", maxRetries, lastErr)
}Corrente Scraping con Goroutines
Il modello di convalutazione di Go è la sua superpotenza. Con goroutine e canali, è possibile raschiare centinaia di URL contemporaneamente mantenendo l'utilizzo della memoria minimo.
package main
import (
"context"
"fmt"
"sync"
proxyhat "github.com/ProxyHatCom/go-sdk"
)
type Result struct {
URL string
StatusCode int
Body string
Err error
}
func scrape(ctx context.Context, client *proxyhat.Client, urls []string, concurrency int) []Result {
results := make([]Result, len(urls))
sem := make(chan struct{}, concurrency) // semaphore
var wg sync.WaitGroup
for i, u := range urls {
wg.Add(1)
go func(idx int, target string) {
defer wg.Done()
sem <- struct{}{} // acquire
defer func() { <-sem }() // release
resp, err := client.Get(ctx, target)
if err != nil {
results[idx] = Result{URL: target, Err: err}
return
}
results[idx] = Result{
URL: target,
StatusCode: resp.StatusCode,
Body: string(resp.Body),
}
}(i, u)
}
wg.Wait()
return results
}
func main() {
client, _ := proxyhat.NewClient(proxyhat.Config{
Username: "your_username",
Password: "your_password",
ProxyType: proxyhat.Residential,
})
defer client.Close()
urls := []string{
"https://example.com/page/1",
"https://example.com/page/2",
"https://example.com/page/3",
// ... hundreds more
}
results := scrape(context.Background(), client, urls, 20)
for _, r := range results {
if r.Err != nil {
fmt.Printf("FAIL %s: %v\n", r.URL, r.Err)
} else {
fmt.Printf("OK %s: %d bytes\n", r.URL, len(r.Body))
}
}
}Limitare il tasso con un Semaphore
Il raschietto sopra già utilizza un canale semaforo per cap concurrency. Per limitare i tassi più elevati (ad esempio, richieste N al secondo), utilizzare golang.org/x/time/rate:
package main
import (
"context"
"fmt"
"log"
proxyhat "github.com/ProxyHatCom/go-sdk"
"golang.org/x/time/rate"
)
func main() {
client, _ := proxyhat.NewClient(proxyhat.Config{
Username: "your_username",
Password: "your_password",
ProxyType: proxyhat.Residential,
})
defer client.Close()
// Allow 10 requests per second, burst of 20
limiter := rate.NewLimiter(10, 20)
urls := []string{"https://example.com/1", "https://example.com/2"}
for _, u := range urls {
if err := limiter.Wait(context.Background()); err != nil {
log.Fatal(err)
}
resp, err := client.Get(context.Background(), u)
if err != nil {
fmt.Printf("Error: %v\n", err)
continue
}
fmt.Printf("%s — %d\n", u, resp.StatusCode)
}
}Consigli di produzione
Collegamento piscina
Vai! http.Transport mantiene un pool di connessioni idle per impostazione predefinita. Per i carichi di lavoro proxy, sintonizzare queste impostazioni:
transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
MaxIdleConns: 200,
MaxIdleConnsPerHost: 50,
MaxConnsPerHost: 100,
IdleConnTimeout: 90 * time.Second,
ResponseHeaderTimeout: 15 * time.Second,
}Timeouts
Impostare sempre i timeout. Un raschietto senza timeout alla fine appenderà su una connessione bloccata:
client := &http.Client{
Transport: transport,
Timeout: 30 * time.Second, // total request timeout
}
// Or use context for per-request control
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", targetURL, nil)
resp, err := client.Do(req)Grazioso arresto
In raschietti lunghi, ascoltare i segnali del sistema operativo per spegnere in modo pulito:
package main
import (
"context"
"os"
"os/signal"
"syscall"
)
func main() {
ctx, stop := signal.NotifyContext(
context.Background(),
os.Interrupt, syscall.SIGTERM,
)
defer stop()
// Pass ctx to your scraping functions
// When Ctrl+C is pressed, ctx is cancelled
// and in-flight requests wind down gracefully
runScraper(ctx)
}Registrazione e osservabilità
Avvolgi il tuo trasporto HTTP per registrare i tempi di richiesta e i codici di stato. Questo aiuta a identificare obiettivi lenti e errori proxy nella produzione:
type loggingTransport struct {
inner http.RoundTripper
}
func (t *loggingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
start := time.Now()
resp, err := t.inner.RoundTrip(req)
elapsed := time.Since(start)
if err != nil {
log.Printf("ERR %s %s (%v) err=%v", req.Method, req.URL, elapsed, err)
} else {
log.Printf("OK %s %s (%v) status=%d", req.Method, req.URL, elapsed, resp.StatusCode)
}
return resp, err
}Asporto chiave
- Go's goroutines + proxies = massiccia concurrency. È possibile eseguire migliaia di richieste di proxy-routed con memoria minima in testa.
- Il ProxyHat Go SDK gestisce l'autenticazione, retries, sessioni e geo-targeting con una API pulita. Installarlo per saltare la caldaia.
- Utilizzare IP rotanti per la raschiatura a scala e sessioni appiccicose per flussi di lavoro multi-step come flussi di login.
- Impostare sempre timeout su entrambi
http.Cliente viacontext.WithTimeoutper il controllo delle richieste.- Tasso limite responsabile con
golang.org/x/time/ratee cap concurrency con canali semafori.- Geo-target le tue richieste passando un codice paese per accedere 190+ sedi in tutto il mondo.
- Controlla la nostra guida migliori proxy per la raschiatura web scegliere il piano giusto per il carico di lavoro.






