Go 爬虫代理开发示例

[!NOTE]代码示例说明

  1. 代码样例不能直接运行,请替换成您自己的代理信息。
  2. 在不同编程语言的代码示例中,需注意其环境版本。
  3. 示例代码使用遇到问题请联系售后客服,我们会为您提供技术支持。

net/http

package main

import (
    "net/url"
    "net/http"
    "bytes"
    "fmt"
    "io/ioutil"
)

// 代理服务器(产品官网 www.16yun.cn)
const ProxyServer = "t.16yun.cn:31111"

type ProxyAuth struct {
    Username string
    Password string
}

func (p ProxyAuth) ProxyClient() http.Client {

    var proxyURL *url.URL
    if p.Username != ""&& p.Password!="" {
        proxyURL, _ = url.Parse("http://" + p.Username + ":" + p.Password + "@" + ProxyServer)
    }else{
        proxyURL, _ = url.Parse("http://" + ProxyServer)
    }
    return http.Client{Transport: &http.Transport{Proxy:http.ProxyURL(proxyURL)}}
}

func main()  {


    targetURI := "https://httpbin.org/ip"


    // 初始化 proxy http client
    client := ProxyAuth{"username",  "password"}.ProxyClient()

    request, _ := http.NewRequest("GET", targetURI, bytes.NewBuffer([] byte(``)))

    // 设置Proxy-Tunnel
    // rand.Seed(time.Now().UnixNano())
    // tunnel := rand.Intn(10000)
    // request.Header.Set("Proxy-Tunnel", strconv.Itoa(tunnel) )

    response, err := client.Do(request)

    if err != nil {
        panic("failed to connect: " + err.Error())
    } else {
        bodyByte, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Println("读取 Body 时出错", err)
            return
        }
        response.Body.Close()

        body := string(bodyByte)

        fmt.Println("Response Status:", response.Status)
        fmt.Println("Response Header:", response.Header)
        fmt.Println("Response Body:\n", body)
    }
}

net/http(支持Proxy-Tunnel)

package main

import (
    "crypto/tls"
    "fmt"
    "io/ioutil"
    "net"
    "net/http"
    "net/http/httputil"
    "net/url"
    "time"
)

func main() {

    for {
        // 代理服务器的用户名和密码
        proxyUsername := "username"
        proxyPassword := "password"
        // 代理服务器(产品官网 www.16yun.cn)
        // 代理服务器的 URL
        proxyURL, err := url.Parse(fmt.Sprintf("http://%s:%s@t.16yun.cn:31111", proxyUsername, proxyPassword))
        if err != nil {
            fmt.Println(err)
            return
        }
        // 添加自定义头部,
        //rand.Seed(time.Now().UnixNano())
        //tunnel := rand.Intn(10000)
        //proxyHeaders.Add("Proxy-Tunnel", strconv.Itoa(tunnel))

        proxyHeaders := http.Header{}
        // 设置为固定的数字 ,后面所有请求都会固定到一个IP上
        // proxyHeaders.Add("Proxy-Tunnel", "1")
        
        // 定制Transport
        tr := &http.Transport{
            Proxy:           http.ProxyURL(proxyURL),
            TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 如果需要跳过证书验证
            // 自定义DialContext函数
            DialContext: (&net.Dialer{
                Timeout:   30 * time.Second,
                KeepAlive: 30 * time.Second,
                DualStack: true,
            }).DialContext,
            ProxyConnectHeader: proxyHeaders,
        }
        // 定制Client
        client := &http.Client{

            Transport: tr,
        }

        // 发起请求
        req, err := http.NewRequest("GET", "https://httpbin.org/ip", nil)
        if err != nil {
            fmt.Println(err)
            return
        }

        // 使用httputil.DumpRequest输出完整的请求
        dump, err := httputil.DumpRequestOut(req, true)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println(string(dump))

        // 发送请求
        resp, err := client.Do(req)
        if err != nil {
            fmt.Println("error")
            fmt.Println(err)
            return
        }
        defer resp.Body.Close()
        // 读取响应体
        body, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            fmt.Println(err)
            return
        }

        // 打印响应体
        fmt.Println("Response Body:", string(body))
        time.Sleep(time.Second * 1)
    }

}