package requests import ( "fmt" "log" "net/http" "net/url" "github.com/PuerkitoBio/goquery" "github.com/go-redis/redis" "golang.org/x/net/proxy" ) const ( redisAddr = "127.0.0.1:6379" torAddr = "socks5://127.0.0.1:9050" defaultAgent = "Mozilla/5.0 (X11; Linux x86_64…) Gecko/20100101 Firefox/68.0" ) var cli *http.Client var red *redis.Client func init() { proxyUrl, err := url.Parse(torAddr) if err != nil { log.Fatalf("error while parsing torAddr %s : %s", torAddr, err) } dialer, err := proxy.FromURL(proxyUrl, proxy.Direct) if err != nil { log.Fatalf("error while creating dialer : %s", err) } transport := &http.Transport{ Dial: dialer.Dial, } cli = &http.Client{ Transport: transport, } red = redis.NewClient(&redis.Options{ Addr: redisAddr, }) if pong := red.Ping().Val(); pong != "PONG" { log.Fatalf("unexpected response from redis PING conmmand : %s", pong) } } func GetDocumentFromURL(url string) (*goquery.Document, error) { req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, fmt.Errorf("error while building request: %s", err) } agent := red.SRandMember("agents").Val() if agent == "" { agent = defaultAgent } req.Header.Set("User-Agent", agent) resp, err := cli.Do(req) if err != nil { return nil, fmt.Errorf("error while sending request: %s", err) } defer func() { if err := resp.Body.Close(); err != nil { log.Fatalf("error while closing body for %s : %s", url, err) } }() doc, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { return nil, fmt.Errorf("error while parsing response: %s", err) } return doc, nil }