求教:爬虫在多ip主机运行的时候,如何切换对外请求的ip

dtbu · 2022-08-23 13:47:19 · 2445 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2022-08-23 13:47:19 的主题,其中的信息可能已经有所发展或是发生改变。

求教各位go大佬, 我的爬虫部署在一台多ip主机,请问如何切换对外请求的ip?


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2445 次点击  
加入收藏 微博
8 回复  |  直到 2022-08-31 13:03:42
jan-bar
jan-bar · #1 · 3年之前
package main

import (
    "context"
    "flag"
    "io"
    "net"
    "net/http"
    "os"
)

func main() {
    src := flag.String("ip", "", "src ip")
    dst := flag.String("url", "https://www.baidu.com", "get url")
    flag.Parse()

    resp, err := IpGet(*src, *dst)
    if err != nil {
        panic(err)
    }
    //goland:noinspection GoUnhandledErrorResult
    defer resp.Body.Close()

    _, err = io.Copy(os.Stdout, resp.Body)
    if err != nil {
        panic(err)
    }
}

func IpGet(srcIP, url string) (*http.Response, error) {
    c := http.Client{
        Transport: &http.Transport{
            DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
                ra, err := net.ResolveTCPAddr(network, addr)
                if err != nil {
                    return nil, err
                }
                var la *net.TCPAddr
                if srcIP != "" {
                    // 指定本地源网卡"IP:0",端口为0表示自动分配
                    la, err = net.ResolveTCPAddr(network, srcIP)
                    if err != nil {
                        return nil, err
                    }
                }
                return net.DialTCP(network, la, ra)
            },
        },
    }
    return c.Get(url)
}

执行go run main.go -ip 1.2.3.4:0,表示用IP为1.2.3.4端口随机的源地址请求,而该IP就是你要指定网卡的IP就可以了。

dtbu
dtbu · #2 · 3年之前

<code>package main

import ( "fmt" "net/http" ) func main() { ipList := [5]string{"192.168.1.2", "192.168.1.3", "192.168.1.4", "192.168.1.5", "192.168.1.6"} searchUrl := "http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=1221&#34; searchRequest, err := http.NewRequest("GET", searchUrl, nil) if err != nil { fmt.Println(err) } client := &http.Client{} searchIndex, err := client.Do(searchRequest) if err != nil { fmt.Println(err) } defer searchIndex.Body.Close() fmt.Print(searchIndex) } </code>

请教楼上大佬,假如我服务器的ip地址事先存入了数组ipList,如何在发起http请求的时候,使用这些ip来对外访问呢.

jan-bar
jan-bar · #3 · 3年之前
dtbudtbu #2 回复

package main import ( "fmt" "net/http" ) func main() { ipList := [5]string{"192.168.1.2", "192.168.1.3", "192.168.1.4", "192.168.1.5", "192.168.1.6"} searchUrl := "http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=1221" searchRequest, err := http.NewRequest("GET", searchUrl, nil) if err != nil { fmt.Println(err) } client := &http.Client{} searchIndex, err := client.Do(searchRequest) if err != nil { fmt.Println(err) } defer searchIndex.Body.Close() fmt.Print(searchIndex) } 请教楼上大佬,假如我服务器的ip地址事先存入了数组ipList,如何在发起http请求的时候,使用这些ip来对外访问呢.

按照我上面的示例去指定发起请求的源网卡ip吧。

dtbu
dtbu · #4 · 3年之前

Transport: &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { } }

已经可以,虽然这些还看不懂,但是已经成功实现了。

summers
summers · #5 · 3年之前

mark

zzustu
zzustu · #6 · 3年之前
jan-barjan-bar #1 回复

```go package main import ( "context" "flag" "io" "net" "net/http" "os" ) func main() { src := flag.String("ip", "", "src ip") dst := flag.String("url", "https://www.baidu.com", "get url") flag.Parse() resp, err := IpGet(*src, *dst) if err != nil { panic(err) } //goland:noinspection GoUnhandledErrorResult defer resp.Body.Close() _, err = io.Copy(os.Stdout, resp.Body) if err != nil { panic(err) } } func IpGet(srcIP, url string) (*http.Response, error) { c := http.Client{ Transport: &http.Transport{ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { ra, err := net.ResolveTCPAddr(network, addr) if err != nil { return nil, err } var la *net.TCPAddr if srcIP != "" { // 指定本地源网卡"IP:0",端口为0表示自动分配 la, err = net.ResolveTCPAddr(network, srcIP) if err != nil { return nil, err } } return net.DialTCP(network, la, ra) }, }, } return c.Get(url) } ``` 执行`go run main.go -ip 1.2.3.4:0`,表示用IP为`1.2.3.4`端口随机的源地址请求,而该IP就是你要指定网卡的IP就可以了。

不错,原来//goland:noinspection GoUnhandledErrorResult可以抑制 GoLand 未处理 err 警告,还有没有别的用法

jan-bar
jan-bar · #7 · 3年之前
zzustuzzustu #6 回复

#1楼 @jan-bar 不错,原来`//goland:noinspection GoUnhandledErrorResult`可以抑制 GoLand 未处理 err 警告,还有没有别的用法

只需要对着不顺眼的地方敲Alt + Enter,那里面的几个选项你自己试试吧。

image.png

我有强迫症,必须要把右上角的红色错误,黄色警告,绿色不合法全部消掉,变成下面那种没问题的绿色。

image.png

zzustu
zzustu · #8 · 3年之前
jan-barjan-bar #7 回复

#6楼 @zzustu 只需要对着不顺眼的地方敲`Alt + Enter`,那里面的几个选项你自己试试吧。 ![image.png](https://static.golangjob.cn/220831/ea8978722344d52e165fd3d90d889525.png) 我有强迫症,必须要把右上角的红色错误,黄色警告,绿色不合法全部消掉,变成下面那种没问题的绿色。 ![image.png](https://static.golangjob.cn/220831/a830a7b63c39fb59e109fbb5151321a2.png)

🙆‍

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传