Pourquoi utiliser Proxies dans Go?
Go est devenu le langage de choix pour les outils de réseautage haute performance, les racleurs web et les clients API. Ses goroutines légères, ses primitifs de concurrence intégrés, et une bataille éprouvée net/http bibliothèque standard le rendent idéal pour les applications alimentées par proxy qui doivent traiter des milliers de requêtes concurrentes.
Que vous construisiez une grattage de la toile pipeline, surveillance Classement SERP, ou la collecte de données de tarification compétitives, le routage de vos clients Go HTTP à travers des proxys vous permet de tourner les adresses IP, de contourner les géo-restrictions et d'éviter les limites de taux à l'échelle.
Dans ce guide, vous apprendrez à configurer proxies in Go utilisant à la fois la bibliothèque standard et la ProxyHat Go SDK. Chaque extrait de code est prêt à copier-coller afin que vous puissiez commencer à gratter en quelques minutes.
Installation
ProxyHat Go SDK
La façon la plus rapide de commencer est avec le SDK officiel. Il s'occupe de l'authentification, de la rotation, du géo-ciblage et des relevés hors de la boîte.
go get github.com/ProxyHatCom/go-sdk@latestBibliothèque standard seulement
Si vous préférez zéro dépendance, Go's net/http et net/url Les paquets sont tout ce dont vous avez besoin. Aucune installation supplémentaire nécessaire.
Authentification et configuration de base
ProxyHat utilise l'authentification nom d'utilisateur-mot de passe sur le paramètre proxy. Vous trouverez vos références dans le Tableau de bord ProxyHat. Une URL proxy typique ressemble à ceci :
http://USERNAME:PASSWORD@gate.proxyhat.com:8080Gardez les références hors du code source. Utiliser des variables d'environnement ou .env fichier & #160;:
export PROXYHAT_USER="your_username"
export PROXYHAT_PASS="your_password"Simple GET Demande avec un mandataire
Voici l'approche minimale en utilisant seulement la bibliothèque 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))
}Exécutez-le et vous verrez une adresse IP résidentielle au lieu de votre propre. Chaque demande est acheminée par ProxyHat Pool de procurations résidentielles.
Utilisation de différents types de proxy
ProxyHat prend en charge trois types de proxy, chacun adapté aux différentes charges de travail. Vous sélectionnez le type via le port proxy ou un nom d'utilisateur :
| Type | Port | Meilleur pour | Latence |
|---|---|---|---|
| Résidentiel | 8000 | Dégraissage, vérification de la publicité | ~800 ms |
| Centre de données | 8010 | Demandes groupées à grande vitesse | ~200 ms |
| Mobile | 8020 | Médias sociaux, tests d'applications | ~1200 ms |
Pour une comparaison plus approfondie de l'utilisation de chaque type, voir notre guide sur proxies résidentiels vs datacenter vs mobiles.
// 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"Approche manuelle: Go net/http avec la configuration Proxy
Pour le contrôle complet, configurez le http.Transport directement. Cela vous permet d'accorder le billard de connexion, les paramètres TLS et les timeouts:
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
}Approche recommandée : ProxyHat Go SDK
Les ProxyHat Go SDK enveloppe toute la plaque de chaudière dans une API propre. Il gère le pooling de connexion, les relevés automatiques, la gestion de session et la géo-cible pour vous.
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))
}Le SDK retourne une réponse structurée, gère la décompression et résout automatiquement les défaillances transitoires. Vérifiez Documentation API pour la référence complète de la méthode.
Sessions rotatives et séances collantes
ProxyHat prend en charge deux modes de session :
- Rotation (par défaut) — chaque demande obtient une nouvelle IP. Idéal pour grande échelle grattage de la toile.
- Sticky — la même IP est maintenue pour une durée configurable (jusqu'à 30 minutes). Utile pour les flux multi-étapes comme les séquences de connexion ou les rampes paginées.
Séances de rotation (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))
}Séances collantes (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)Séances collantes (manuelles)
// Append session ID to the username
// Format: USERNAME-session-SESSIONID
proxyURL := "http://user-session-abc123:pass@gate.proxyhat.com:8080"Demandes géographiées
Besoin de PI d'un pays donné? Prise en charge de proxyHat 190 sites et plus. Passez le code de pays via le SDK ou comme indicateur de nom d'utilisateur:
// 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"Le géo-ciblage est essentiel pour la localisation Suivi SERP, contrôles régionaux des prix et tests de disponibilité du contenu.
Gestion des erreurs et retraits
Les requêtes réseau via les proxies peuvent échouer pour des raisons transitoires : réinitialisation de la connexion, timeouts ou blocs temporaires. La manipulation d'erreurs robustes est essentielle pour les racleurs de production.
Récupérations intégrées SDK
client, _ := proxyhat.NewClient(proxyhat.Config{
Username: "your_username",
Password: "your_password",
ProxyType: proxyhat.Residential,
MaxRetries: 3,
RetryDelay: 2 * time.Second,
})Réessayer manuellement avec un recul exponentiel
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)
}Dégraissage simultané avec des Goroutines
Le modèle de proximité de Go est sa superpuissance. Avec les goroutines et les canaux, vous pouvez gratter des centaines d'URL simultanément tout en gardant l'utilisation de la mémoire minimale.
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))
}
}
}Limite de vitesse avec un Sémaphore
Le racleur au-dessus utilise déjà un canal sémaphore pour capter la concurrence. Pour limiter le taux de grains fins (p. ex., demandes de N par seconde), utiliser 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)
}
}Conseils de production
Mise en commun des connexions
Allez http.Transport maintient une réserve de connexions par défaut. Pour les charges de travail proxy, régler ces paramètres :
transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
MaxIdleConns: 200,
MaxIdleConnsPerHost: 50,
MaxConnsPerHost: 100,
IdleConnTimeout: 90 * time.Second,
ResponseHeaderTimeout: 15 * time.Second,
}Délais
Toujours régler les horaires. Un racleur sans timeouts finira par s'accrocher à une connexion bloquée :
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)Arrêt gracieux
Dans les grattoirs de longue durée, écoutez les signaux OS pour s'arrêter proprement :
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)
}Exploitation forestière et observation
Enveloppez votre transport HTTP pour enregistrer le calendrier des requêtes et les codes d'état. Cela permet d'identifier les cibles lentes et les erreurs de remplacement dans la production:
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
}A emporter des clés
- Go's goroutines + proxies = accord massif. Vous pouvez exécuter des milliers de requêtes via proxy avec un minimum de mémoire.
- Le ProxyHat Go SDK gère l'authentification, les relevés, les sessions et la géo-ciblage avec une API propre. Installez-le pour sauter la plaque de chaudière.
- Utiliser des IP tournants pour la démolition à l'échelle et sessions collantes pour les workflows multi-étapes comme les flux de connexion.
- Toujours définir les timeouts sur les deux
http.Clientet parcontext.WithTimeoutpour le contrôle par demande.- Limite de taux responsable avec
golang.org/x/time/rateet de la cohérence avec les canaux sémaphores.- Géo-ciblez vos demandes en passant un code pays à l'accès 190 sites et plus mondial.
- Consultez notre guide meilleurs proxies pour le grattage de toile choisir le bon plan pour votre charge de travail.
Foire aux questions
Comment configurer un proxy dans le client Net/http de Go ?
Définir la Proxy sur http.Transport à http.ProxyURL(parsedURL) où parsedURL est votre adresse mandataire analysée avec url.Parse(). Puis passer le transport à http.Client. La bibliothèque standard gère automatiquement le tunnelage CONNECT pour les cibles HTTPS.
Le ProxyHat Go SDK supporte-t-il les cibles HTTPS ?
Oui. Le SDK utilise un tunnel HTTP CONNECT sous le capot, de sorte que tout le trafic HTTPS est chiffré de bout en bout entre votre client et le serveur cible. Le proxy ne voit que le nom d'hôte de destination.
Combien de demandes simultanées puis-je faire par Go proxies ?
Les goroutines de Go sont extrêmement légères (environ 4 KB de pile chacun), de sorte que vous pouvez exécuter des dizaines de milliers simultanément. La limite pratique est votre ProxyHat plan's l'allocation de connexion simultanée et la capacité du serveur cible. Utilisez un canal sémaphore pour capter la concordance à un niveau sûr.
Quelle est la différence entre les sessions de procuration tournantes et collantes?
Les sessions tournantes attribuent une nouvelle adresse IP à chaque requête, ce qui est idéal pour le grattage large. Les sessions collantes conservent la même IP pendant une durée définie (jusqu'à 30 minutes), ce qui les rend adaptées aux flux multi-étapes où la cible attend un visiteur cohérent, comme les séquences de connexion ou les pages de caisse.
Comment puis-je gérer les erreurs de proxy et les relevés dans Go?
Le SDK ProxyHat Go fournit une logique de réessayer intégrée avec configurable MaxRetries et RetryDelay. Si vous utilisez la bibliothèque standard, implémentez une sauvegarde exponentielle en enveloppant votre demande dans une boucle qui double le délai après chaque tentative ratée. Vérifiez toujours les erreurs réseau et les codes d'état HTTP 5xx.






