Go语言爬虫代码使用代理API

139 阅读3分钟

我们使用Go语言编写一个爬虫,通过API提取代理IP,并使用这些代理IP来访问目标网站。 我们将编写一个简单的程序,由于代理的可用性不确定,这里我会尝试使用不同的代理直到成功或全部尝试完毕。

a2.png

以下是一个使用 Go 语言编写的爬虫代码,它通过代理 API 获取代理列表,并使用随机代理访问目标网站:

package main
​
import (
    "bufio"
    "encoding/json"
    "fmt"
    "io"
    "math/rand"
    "net/http"
    "net/url"
    "os"
    "time"
)
​
// 代理 API 响应结构体 (根据实际 API 响应调整)
type ProxyResponse struct {
    Data []struct {
        IP   string `json:"ip"`
        Port int    `json:"port"`
    } `json:"data"`
}
​
func main() {
    // 代理 API 地址 (替换为实际 API 地址)
    proxyAPI := "https://proxy-provider.com/api/get-proxies?type=http&count=10"
    // 目标网站 URL
    targetURL := "https://httpbin.org/ip"// 步骤 1: 从 API 获取代理列表
    proxies, err := fetchProxies(proxyAPI)
    if err != nil {
        fmt.Printf("获取代理失败: %v\n", err)
        return
    }
    fmt.Printf("共获取 %d 个代理\n", len(proxies))
​
    // 步骤 2: 随机选择一个代理
    rand.Seed(time.Now().UnixNano())
    proxyAddr := proxies[rand.Intn(len(proxies))]
    fmt.Printf("使用代理: %s\n", proxyAddr)
​
    // 步骤 3: 使用代理发送请求
    resp, err := sendRequestWithProxy(targetURL, proxyAddr)
    if err != nil {
        fmt.Printf("请求失败: %v\n", err)
        return
    }
    defer resp.Body.Close()
​
    // 步骤 4: 处理响应
    body, _ := io.ReadAll(resp.Body)
    fmt.Printf("响应状态: %d\n内容:\n%s\n", resp.StatusCode, body)
}
​
// 从 API 获取代理列表
func fetchProxies(apiURL string) ([]string, error) {
    resp, err := http.Get(apiURL)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
​
    // 根据 API 实际返回格式处理 (示例为 JSON 格式)
    var proxyResp ProxyResponse
    if err := json.NewDecoder(resp.Body).Decode(&proxyResp); err != nil {
        // 如果 API 返回文本格式 (每行一个代理)
        return parseTextProxies(resp.Body)
    }
​
    // 处理 JSON 格式响应
    var proxies []string
    for _, p := range proxyResp.Data {
        proxies = append(proxies, fmt.Sprintf("%s:%d", p.IP, p.Port))
    }
    return proxies, nil
}
​
// 解析文本格式代理 (ip:port 每行一个)
func parseTextProxies(body io.Reader) ([]string, error) {
    var proxies []string
    scanner := bufio.NewScanner(body)
    for scanner.Scan() {
        proxies = append(proxies, scanner.Text())
    }
    return proxies, scanner.Err()
}
​
// 通过代理发送 HTTP 请求
func sendRequestWithProxy(targetURL, proxyAddr string) (*http.Response, error) {
    // 设置代理
    proxyURL, err := url.Parse("http://" + proxyAddr)
    if err != nil {
        return nil, err
    }
​
    transport := &http.Transport{
        Proxy: http.ProxyURL(proxyURL),
    }
​
    client := &http.Client{
        Transport: transport,
        Timeout:   10 * time.Second,
    }
​
    // 创建请求
    req, err := http.NewRequest("GET", targetURL, nil)
    if err != nil {
        return nil, err
    }
​
    // 设置请求头 (模拟浏览器)
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
​
    // 发送请求
    return client.Do(req)
}

使用说明:

1、替换代理 API

  • proxyAPI 变量替换为实际的代理服务商 API
  • 示例 API 格式假设返回 JSON:{"data": [{"ip":"1.2.3.4", "port":8080}, ...]}
  • 如果 API 返回文本格式(每行一个 ip:port),代码会自动处理

2、配置目标 URL

  • 修改 targetURL 为你要爬取的目标网站
  • 示例使用 httpbin.org 进行测试

3、安装依赖

go mod init proxy-crawler
go mod tidy

4、运行代码

go run main.go

功能特点:

  1. 自动获取代理列表
  2. 随机选择代理服务器
  3. 支持 HTTP 代理
  4. 模拟浏览器 User-Agent
  5. 自动处理 JSON/文本格式代理
  6. 10 秒超时设置

自定义选项:

  • 增加重试机制:遇到失败时更换代理重试

  • 添加代理验证:检查代理可用性

  • 设置请求频率:添加 time.Sleep() 避免被封

  • 使用 HTTPS 代理:修改代理 URL 为 https://

  • 添加代理认证

    proxyURL := fmt.Sprintf("http://user:pass@%s", proxyAddr)
    

最后需要提醒的是,在实际使用时,请根据代理服务商提供的 API 文档调整响应解析逻辑。了解API提取频率限制以及了解网站规则,避免超量提取使用请求导致触发反爬机制,这样正向循环才能更高效的获取你想要的数据。