mirror of
https://github.com/ProudMuBai/GoFilm.git
synced 2026-02-04 06:54:41 +08:00
127 lines
3.7 KiB
Go
127 lines
3.7 KiB
Go
package util
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/gocolly/colly/v2"
|
|
"github.com/gocolly/colly/v2/extensions"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
/*
|
|
网络请求, 数据爬取
|
|
*/
|
|
|
|
var (
|
|
Client = CreateClient()
|
|
)
|
|
|
|
// RequestInfo 请求参数结构体
|
|
type RequestInfo struct {
|
|
Uri string `json:"uri"` // 请求url地址
|
|
Params url.Values `json:"param"` // 请求参数
|
|
Header http.Header `json:"header"` // 请求头数据
|
|
Resp []byte `json:"resp"` // 响应结果数据
|
|
Err string `json:"err"` // 错误信息
|
|
}
|
|
|
|
// RefererUrl 记录上次请求的url
|
|
var RefererUrl string
|
|
|
|
// CreateClient 初始化请求客户端
|
|
func CreateClient() *colly.Collector {
|
|
c := colly.NewCollector()
|
|
|
|
// 设置请求使用clash的socks5代理
|
|
//setProxy(c)
|
|
|
|
// 设置代理信息
|
|
//if proxy, err := proxy.RoundRobinProxySwitcher("127.0.0.1:7890"); err != nil {
|
|
// c.SetProxyFunc(proxy)
|
|
//}
|
|
// 设置并发数量控制
|
|
//c.Async = true
|
|
// 访问深度
|
|
c.MaxDepth = 1
|
|
//可重复访问
|
|
c.AllowURLRevisit = true
|
|
// 设置超时时间 默认10s
|
|
c.SetRequestTimeout(20 * time.Second)
|
|
// 发起请求之前会调用的方法
|
|
c.OnRequest(func(request *colly.Request) {
|
|
// 设置一些请求头信息
|
|
request.Headers.Set("Content-Type", "application/json;charset=UTF-8")
|
|
request.Headers.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
|
|
//request.Headers.Set("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
|
|
// 请求完成后设置请求头Referer
|
|
if len(RefererUrl) <= 0 || !strings.Contains(RefererUrl, request.URL.Host) {
|
|
RefererUrl = ""
|
|
}
|
|
request.Headers.Set("Referer", RefererUrl)
|
|
})
|
|
// 请求期间报错的回调
|
|
c.OnError(func(response *colly.Response, err error) {
|
|
log.Printf("请求异常: URL: %s Error: %s\n", response.Request.URL, err)
|
|
})
|
|
return c
|
|
}
|
|
|
|
// ApiGet 请求数据的方法
|
|
func ApiGet(r *RequestInfo) {
|
|
if r.Header != nil {
|
|
if t, err := strconv.Atoi(r.Header.Get("timeout")); err != nil && t > 0 {
|
|
Client.SetRequestTimeout(time.Duration(t) * time.Second)
|
|
}
|
|
}
|
|
// 设置随机请求头
|
|
extensions.RandomUserAgent(Client)
|
|
//extensions.Referer(Client)
|
|
// 请求成功后的响应
|
|
Client.OnResponse(func(response *colly.Response) {
|
|
if (response.StatusCode == 200 || (response.StatusCode >= 300 && response.StatusCode <= 399)) && len(response.Body) > 0 {
|
|
// 将响应结构封装到 RequestInfo.Resp中
|
|
r.Resp = response.Body
|
|
} else {
|
|
r.Resp = []byte{}
|
|
}
|
|
// 将请求url保存到RefererUrl 用于 Header Refer属性
|
|
RefererUrl = response.Request.URL.String()
|
|
// 拿到response后输出请求url
|
|
//log.Println("\n请求成功: ", response.Request.URL)
|
|
})
|
|
// 处理请求参数
|
|
err := Client.Visit(fmt.Sprintf("%s?%s", r.Uri, r.Params.Encode()))
|
|
if err != nil {
|
|
r.Err = err.Error()
|
|
log.Println("获取数据失败: ", err)
|
|
}
|
|
}
|
|
|
|
// ApiTest 处理API请求后的数据, 主测试
|
|
func ApiTest(r *RequestInfo) error {
|
|
// 请求成功后的响应
|
|
Client.OnResponse(func(response *colly.Response) {
|
|
// 判断请求状态
|
|
if (response.StatusCode == 200 || (response.StatusCode >= 300 && response.StatusCode <= 399)) && len(response.Body) > 0 {
|
|
// 将响应结构封装到 RequestInfo.Resp中
|
|
r.Resp = response.Body
|
|
} else {
|
|
r.Resp = []byte{}
|
|
}
|
|
})
|
|
// 执行请求返回错误结果
|
|
err := Client.Visit(fmt.Sprintf("%s?%s", r.Uri, r.Params.Encode()))
|
|
log.Println(err)
|
|
return err
|
|
}
|
|
|
|
// 本地代理测试
|
|
func setProxy(c *colly.Collector) {
|
|
proxyUrl, _ := url.Parse("socks5://127.0.0.1:7890")
|
|
c.WithTransport(&http.Transport{Proxy: http.ProxyURL(proxyUrl)})
|
|
}
|