196 lines
5.0 KiB
Go
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
|
|
}
|