在golang中使用clash作为http客户端的代理
- 作者:
- 淡白
- 创建时间:
- 2023-07-28 14:23:57
- Go proxy http
摘要:这是一篇使用Clash作为HTTP客户端代理的Go语言教程。在爬取网站时,经常会遇到一些反爬虫的网站,这些网站会检测你的IP地址,如果被检测到是爬虫,就会拒绝访问。为了解决这个问题,可以使用代理来隐藏真实IP地址。代理的原理是将请求发送到代理服务器,代理服务器再发送给目标服务器并返回数据。这样目标服务器无法知道真实IP地址。本文介绍了使用Clash作为HTTP客户端代理的方法。 首先,需要获取HTTP代理。可以通过免费获取或者付费购买的方式来获取。作者选择了使用机场提供的v2或SSR协议的代理。 接下来,将Clash代码引入Go程序中,并设置代理的配置信息。代码中使用了Clash的Start()方法来启动代理,并通过调用Proxies()方法获取代理列表。 然后,使用代理URL并创建http.Transport和http.Client对象。在创建http.Transport对象时,将代理URL传入Proxy字段。最后,通过调用http.Client对象的Get方法来发送请求。 以上就是使用Clash作为HTTP客户端代理的具体实现方法。通过这种方式,可以在Go程序中轻松地使用Clash作为HTTP客户端代理来访问需要隐藏真实IP地址的网站。
在golang中使用clash作为http客户端的代理
在爬取网站时,经常会遇到一些反爬虫的网站,这些网站会检测你的ip地址,如果你的ip地址被检测到是爬虫的话,就会拒绝你的访问,这时候就需要使用代理来解决这个问题。代理的原理就是你的请求先发送给代理服务器,代理服务器再发送给目标服务器,目标服务器返回数据给代理服务器,代理服务器再返回给你。这样的话,目标服务器就无法知道你的真实ip地址,从而达到隐藏你的真实ip地址的目的。网上有一些免费的获取http代理的网站或者可以采用付费购买的方式获取http代理。
我这里我想采用机场来做我的http代理但是机场一般提供的是v2或者ssr协议的代理,恰好clash是用golang写的所以我能在我的golang程序中直接引入clash的代码开启一个本地端口进行代理。
下面是我的代码:
代理实现
package proxy
import (
"bytes"
"encoding/json"
"fmt"
"github.com/Dreamacro/clash/config"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/hub"
logs "github.com/danbai225/go-logs"
"go.uber.org/automaxprocs/maxprocs"
"io"
"math/rand"
"net/http"
"net/url"
"os"
"path/filepath"
"sync"
"time"
)
func init() {
rand.NewSource(time.Now().UnixNano())
}
type Clash struct {
configPath string
}
func New(configPath string) *Clash {
return &Clash{configPath: configPath}
}
func (c *Clash) Start() {
maxprocs.Set(maxprocs.Logger(func(string, ...any) {}))
C.SetHomeDir(".")
if c.configPath != "" {
if !filepath.IsAbs(c.configPath) {
currentDir, _ := os.Getwd()
c.configPath = filepath.Join(currentDir, c.configPath)
}
C.SetConfig(c.configPath)
} else {
configFile := filepath.Join(C.Path.HomeDir(), C.Path.Config())
C.SetConfig(configFile)
}
if err := config.Init(C.Path.HomeDir()); err != nil {
logs.Err("Initial configuration directory error: %s", err.Error())
return
}
if err := hub.Parse(hub.WithExternalController(":9091")); err != nil {
logs.Err("Parse config error: %s", err.Error())
return
}
time.Sleep(time.Second * 1)
c.Speed()
c.RandomSelect()
}
func (c *Clash) Speed() {
proxies := c.Proxies()
group := sync.WaitGroup{}
for _, s := range proxies {
group.Add(1)
go func() {
http.Get(fmt.Sprintf(`http://127.0.0.1:9091/proxies/%s/delay?timeout=5000&url=%s`, url.PathEscape(s.Name), url.QueryEscape(`https://baidu.com`)))
group.Done()
}()
}
group.Wait()
}
func (c *Clash) Proxies() []P {
resp, _ := http.Get(`http://127.0.0.1:9091/proxies`)
all, _ := io.ReadAll(resp.Body)
m := make(map[string]interface{})
m2 := make(map[string]P)
json.Unmarshal(all, &m)
marshal, _ := json.Marshal(m["proxies"])
json.Unmarshal(marshal, &m2)
ps := make([]P, 0)
for k := range m2 {
ps = append(ps, m2[k])
}
return ps
}
func (c *Clash) Switchover(name string) {
json := fmt.Sprintf(`{"name":"%s"}`, name)
req, err := http.NewRequest(http.MethodPut, "http://127.0.0.1:9091/proxies/GLOBAL", bytes.NewBufferString(json))
if err != nil {
logs.Err(err)
return
}
req.Header.Set("Content-Type", "application/json")
_, err = http.DefaultClient.Do(req)
if err != nil {
logs.Err(err)
return
}
}
func (c *Clash) EffectiveProxy() []P {
ps := make([]P, 0)
for _, p := range c.Proxies() {
if len(p.History) > 0 && p.History[len(p.History)-1].Delay > 0 {
ps = append(ps, p)
}
}
return ps
}
func (c *Clash) RandomSelect() string {
ps := c.EffectiveProxy()
name := ps[rand.Int63n(int64(len(ps)))].Name
c.Switchover(name)
logs.Info("切换为", name)
return name
}
type P struct {
Alive bool `json:"alive"`
History []struct {
Time time.Time `json:"time"`
Delay int `json:"delay"`
MeanDelay int `json:"meanDelay"`
} `json:"history"`
Name string `json:"name"`
Type string `json:"type"`
Udp bool `json:"udp"`
}
使用demo
package main
import (
logs "github.com/danbai225/go-logs"
"io"
"net/http"
"net/url"
"test/proxy"
)
func main() {
clash := proxy.New("clash.yml")
clash.Start()
// 创建代理URL
proxyURL, err := url.Parse("http://127.0.0.1:7799")
if err != nil {
return
}
transport := &http.Transport{
Proxy: http.ProxyURL(proxyURL),
}
c := &http.Client{
Transport: transport,
}
resp, err := c.Get("https://ip.useragentinfo.com/json")
all, err := io.ReadAll(resp.Body)
logs.Info(string(all))
}