gohelpers/pkg/util/fetcher.go
2021-09-17 11:16:38 +08:00

196 lines
5.0 KiB
Go

package util
import (
"bufio"
"bytes"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
"net/url"
"time"
"golang.org/x/net/html/charset"
"golang.org/x/text/encoding"
"golang.org/x/text/encoding/unicode"
"golang.org/x/text/transform"
)
var rateLimiter = time.Tick(20 * time.Millisecond)
func Fetch(url string) ([]byte, error) {
<-rateLimiter
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
//fmt.Println("Error status code", resp.StatusCode)
return nil, fmt.Errorf("error status code: %d", resp.StatusCode)
}
bodyReader := bufio.NewReader(resp.Body)
e := determinEncoding(bodyReader)
utf8Reader := transform.NewReader(bodyReader, e.NewDecoder())
return io.ReadAll(utf8Reader)
}
func FetchHost(reqUrl, proxyIP string) ([]byte, error) {
<-rateLimiter
client := &http.Client{}
//是否使用代理IP
if proxyIP != "" {
proxy, err := url.Parse(proxyIP)
if err != nil {
log.Fatalf("1:%v\n", err)
}
netTransport := &http.Transport{
Proxy: http.ProxyURL(proxy),
MaxIdleConnsPerHost: 10,
ResponseHeaderTimeout: time.Second * time.Duration(5),
}
client = &http.Client{
Timeout: time.Second * 10,
Transport: netTransport,
}
}
req, err := http.NewRequest("GET", reqUrl, nil)
if err != nil {
log.Fatalln(err)
}
req.Header.Set("Host", "www.stats.gov.cn")
//req.Header.Set("Cookie", "_trs_uv=kma79tru_6_1yw6; SF_cookie_1=37059734; wzws_cid=ed0db2d09a630ccd20292459e4bfc8091d460d5990f415e3d928761ee970d90f7ba6254f9c4b8e9b79ad456094d4a1381305d0b065ff9cc539ee1775ec262f946af61ddbed371e2a6dae2bc2041a30fc")
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54")
req.Header.Set("Upgrade-Insecure-Requests", "1")
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
//fmt.Println("Error status code", resp.StatusCode)
return nil, fmt.Errorf("error status code: %d", resp.StatusCode)
}
bodyReader := bufio.NewReader(resp.Body)
e := determinEncoding(bodyReader)
utf8Reader := transform.NewReader(bodyReader, e.NewDecoder())
return io.ReadAll(utf8Reader)
}
// HttpPost 模拟请求方法
func HttpPost(postUrl string, headers map[string]string, jsonMap map[string]interface{}, proxyIP string) ([]byte, error) {
client := &http.Client{}
//转换成postBody
bytesData, err := json.Marshal(jsonMap)
if err != nil {
fmt.Println(err.Error())
return nil, err
}
postBody := bytes.NewReader(bytesData)
//是否使用代理IP
if proxyIP != "" {
//proxy := func(_ *http.Request) (*url.URL, error) {
// return url.Parse(proxyIP)
//}
transport := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
proxyUrl, err := url.Parse(proxyIP)
if err == nil { // 使用传入代理
transport.Proxy = http.ProxyURL(proxyUrl)
}
//&http.Transport{Proxy: proxy}
client = &http.Client{Transport: transport}
} else {
client = &http.Client{}
}
// get请求
req, err := http.NewRequest("GET", postUrl, postBody)
if err != nil {
log.Fatalln(err)
return nil, err
}
for k, v := range headers {
req.Header.Add(k, v)
}
resp, err := client.Do(req)
if err != nil {
log.Fatalln(err)
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
//fmt.Println("Error status code", resp.StatusCode)
return nil, fmt.Errorf("error status code: %d", resp.StatusCode)
}
bodyReader := bufio.NewReader(resp.Body)
e := determinEncoding(bodyReader)
utf8Reader := transform.NewReader(bodyReader, e.NewDecoder())
return io.ReadAll(utf8Reader)
}
func determinEncoding(r *bufio.Reader) encoding.Encoding {
bytes, err := r.Peek(1024)
if err != nil && err != io.EOF {
log.Printf("Fetcher error: %v", err)
return unicode.UTF8
}
e, _, _ := charset.DetermineEncoding(bytes, "")
return e
}
// PostRequest 请求
func PostRequest(url, parameter string) ([]byte, error) {
client := &http.Client{}
byteParameter := bytes.NewBuffer([]byte(parameter))
request, _ := http.NewRequest("POST", url, byteParameter)
request.Header.Set("Content-type", "application/json")
response, _ := client.Do(request)
if response.StatusCode != 200 {
return nil, errors.New("网络请求失败")
}
all, err := io.ReadAll(response.Body)
if err != nil {
return nil, errors.New("读取网络内容失败")
}
return all, nil
}
// PostRequestString 请求
func PostRequestString(url, parameter string) ([]byte, error) {
client := &http.Client{}
byteParameter := bytes.NewBuffer([]byte(parameter))
request, _ := http.NewRequest("POST", url, byteParameter)
request.Header.Set("Content-type", "application/x-www-form-urlencoded")
response, _ := client.Do(request)
if response.StatusCode != 200 {
return nil, errors.New("网络请求失败")
}
all, err := io.ReadAll(response.Body)
if err != nil {
return nil, errors.New("读取网络内容失败")
}
return all, nil
}