Golang Http use socket5 proxy
因為最近想爬取一些網站上的視頻,無奈網站在牆外,只能通過代理進行爬取,因此在網上搜索關於golang使用代理的方法。
功夫不負有心人,最后我搜到了兩張配置方法,趁着現在有空將它們總結一下。
Http和Socket代理經常翻牆的梯子戶經常用到,但是有些可能不怎么知道他們的區別。估計大家已經從它們的名字中看出了區別,http給人的第一感覺就是http協議嘛,也就是在瀏覽器中經常用到的,比如大家上網時輸入的網址:http://www.google.com https://www.google.com等等,其實http代理主要的功能就是代理里客戶機(用戶計算機)進行http訪問,代理瀏覽器進行網頁的訪問。而socket代理給人的第一印象則是socket套接字,沒錯socket代理在代理轉發過程中,只是簡單的傳送數據包,不關心這些數據包是干嘛的是是屬於什么協議什么應用的,正是因此socket代理的速度一般來說比http代理的速度快很多(因為人家不那么多事嘛,專心做好本職工作而已)。socket代理又分為socket4和sockt5代理,其中socket4只能支持TCP協議,而socket5則同時支持TCP協議和UDP協議。
第一種方法: HTTP(S)代理
廢話少扯,直接上代碼
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
)
func main() {
urli := url.URL{}
urlproxy, _ := urli.Parse("https://127.0.0.1:9743")
c := http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(urlproxy),
},
}
if resp, err := c.Get("https://www.google.com"); err != nil {
log.Fatalln(err)
} else {
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("%s\n", body)
}
}
上面這種方法是通過在建立http.Client對象時指定代理地址,其實除了這么一種方式外,還有一種就是通過環境變量來指定代理。代碼如下
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
)
func main() {
// urli := url.URL{}
// urlproxy, _ := urli.Parse("https://127.0.0.1:9743")
os.Setenv("HTTP_PROXY", "http://127.0.0.1:9743")
os.Setenv("HTTPS_PROXY", "https://127.0.0.1:9743")
c := http.Client{
// Transport: &http.Transport{
// Proxy: http.ProxyURL(urlproxy),
// },
}
if resp, err := c.Get("https://www.google.com"); err != nil {
log.Fatalln(err)
} else {
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("%s\n", body)
}
}
這個方法是通過設置環境變量,go會自動配置代理。
第二種方法: Socket5代理
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"golang.org/x/net/proxy"
)
func main() {
// create a socks5 dialer
dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:9742", nil, proxy.Direct)
if err != nil {
fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err)
os.Exit(1)
}
// setup a http client
httpTransport := &http.Transport{}
httpClient := &http.Client{Transport: httpTransport}
// set our socks5 as the dialer
httpTransport.Dial = dialer.Dial
if resp, err := httpClient.Get("https://www.google.com"); err != nil {
log.Fatalln(err)
} else {
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("%s\n", body)
}
}
通過這兩種方法可以實現輕松爬梯。