daShangDao_kfzgw-info/kfztp.go
2025-12-22 19:09:56 +08:00

867 lines
27 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
//import (
// "crypto/md5"
// "encoding/json"
// "fmt"
// "log"
// "math/rand"
// "net/http"
// "net/url"
// "regexp"
// "strconv"
// "strings"
// "sync"
// "time"
//
// "github.com/parnurzeal/gorequest"
//)
//
//// 获取商品模版
//func outGetGoodsTplMsgLinux(token, itemId, proxy string) (map[string]interface{}, error) {
// if token == "" {
// return nil, fmt.Errorf("请先登录获取Token")
// }
//
// url := fmt.Sprintf("https://seller.kongfz.com/pc/itemInfo/getTplFields?itemId=%s&isClone=1&v=%d",
// itemId, time.Now().Unix())
//
// log.Printf("请求URL: %s", url)
//
// // 创建HTTP客户端
// request := gorequest.New()
//
// // 设置代理如果有提供代理URL
// if proxy != "" {
// request.Proxy(proxy)
// log.Printf("使用代理: %s", proxy)
// }
//
// resp, body, errs := request.Get(url).
// Set("Cookie", fmt.Sprintf("PHPSESSID=%s", token)).
// Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36").
// Set("Accept", "application/json, text/plain, */*").
// Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8").
// Set("Referer", "https://seller.kongfz.com/").
// Set("Origin", "https://seller.kongfz.com").
// Timeout(30 * time.Second).
// End()
//
// if len(errs) > 0 {
// return nil, fmt.Errorf("请求失败: %v", errs)
// }
//
// // 检查HTTP状态码
// if resp.StatusCode != http.StatusOK {
// return nil, fmt.Errorf("HTTP错误: %d - %s", resp.StatusCode, resp.Status)
// }
//
// var data map[string]interface{}
// if err := json.Unmarshal([]byte(body), &data); err != nil {
// return nil, fmt.Errorf("解析JSON失败: %w", err)
// }
//
// // 检查API响应状态
// if val, ok := data["status"].(float64); ok && val == 1 {
// return data, nil
// }
//
// return nil, fmt.Errorf("API返回错误: %+v", data)
//}
//
//func main() {
// fmt.Println("=== 孔夫子商品模板API服务 ===")
//
// http.HandleFunc("/api/goodsTemplate", getGoodsTemplateHandler)
// http.HandleFunc("/api/outGetImageByIsbn", getOutGetImageByIsbnHandler)
//
// port := "8989"
// server := &http.Server{
// Addr: ":" + port,
// Handler: nil,
// }
// // 启动服务器
// if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
// fmt.Printf("服务器启动失败: %v\n", err)
// }
//}
//
//// 获取商品模板接口
//func getGoodsTemplateHandler(w http.ResponseWriter, r *http.Request) {
// // 设置响应头
// w.Header().Set("Content-Type", "application/json")
//
// // 只处理GET请求
// if r.Method != http.MethodGet {
// w.WriteHeader(http.StatusMethodNotAllowed)
// json.NewEncoder(w).Encode(map[string]interface{}{
// "success": false,
// "error": "只支持GET请求",
// })
// return
// }
//
// // 获取查询参数
// token := r.URL.Query().Get("token")
// itemId := r.URL.Query().Get("itemId")
// proxy := r.URL.Query().Get("proxy")
//
// // 验证必需参数
// if token == "" || itemId == "" {
// w.WriteHeader(http.StatusBadRequest)
// json.NewEncoder(w).Encode(map[string]interface{}{
// "success": false,
// "error": "缺少必需参数: token 和 itemid",
// "usage": map[string]string{
// "token": "登录Token (PHPSESSID)",
// "itemid": "商品ID",
// "proxy": "代理地址 (可选)",
// },
// "example": "GET /api/goods-template?token=abc123&itemid=123456&proxy=http://proxy:8080",
// })
// return
// }
//
// log.Printf("收到请求 - 商品ID: %s", itemId)
//
// // 调用函数获取商品模板
// result, err := outGetGoodsTplMsgLinux(token, itemId, proxy)
// if err != nil {
// log.Printf("获取商品模板失败: %v", err)
// w.WriteHeader(http.StatusInternalServerError)
// json.NewEncoder(w).Encode(map[string]interface{}{
// "success": false,
// "error": err.Error(),
// })
// return
// }
//
// // 返回成功响应
// json.NewEncoder(w).Encode(map[string]interface{}{
// "success": true,
// "data": result,
// })
//}
//
//func getOutGetImageByIsbnHandler(w http.ResponseWriter, r *http.Request) {
// // 设置响应头
// w.Header().Set("Content-Type", "application/json")
//
// // 只处理GET请求
// if r.Method != http.MethodGet {
// w.WriteHeader(http.StatusMethodNotAllowed)
// json.NewEncoder(w).Encode(map[string]interface{}{
// "success": false,
// "error": "只支持GET请求",
// })
// return
// }
//
// // 获取查询参数
// token := r.URL.Query().Get("token")
// isbn := r.URL.Query().Get("isbn")
// proxyType := r.URL.Query().Get("proxyType")
// username := r.URL.Query().Get("username")
// password := r.URL.Query().Get("password")
// machineCode := r.URL.Query().Get("machineCode")
// //proxy := r.URL.Query().Get("proxy")
//
// // 验证必需参数
// if token == "" || isbn == "" {
// w.WriteHeader(http.StatusBadRequest)
// json.NewEncoder(w).Encode(map[string]interface{}{
// "success": false,
// "error": "缺少必需参数: token 和 isbn",
// "usage": map[string]string{
// "token": "登录Token (PHPSESSID)",
// "isbn": "isbn",
// "proxy": "代理地址 (可选)",
// },
// "example": "GET /api/goods-template?token=abc123&itemid=123456&proxy=http://proxy:8080",
// })
// return
// }
//
// manager, err2 := proxyTypeManager(proxyType, username, password, machineCode)
// if err2 != nil {
// return
// }
// log.Printf("收到请求 - 商品ID: %s", isbn)
//
// // 调用函数获取商品模板
// result, err := OutGetImageByIsbns(token, isbn, manager, 0, 0)
// if err != nil {
// log.Printf("获取商品模板失败: %v", err)
// w.WriteHeader(http.StatusInternalServerError)
// json.NewEncoder(w).Encode(map[string]interface{}{
// "success": false,
// "error": err.Error(),
// })
// return
// }
// // 返回成功响应
// json.NewEncoder(w).Encode(map[string]interface{}{
// "success": true,
// "data": result,
// })
//}
//
//// 条目详情结构体
//type BookInfo struct {
// BookName string `json:"book_name"` // 书名
// Author string `json:"author"` // 作者
// Publisher string `json:"publisher"` // 出版社
// ISBN string `json:"isbn"` // ISBN
// PublicationTime int64 `json:"publication_time"` // 出版时间
// Edition string `json:"edition"` // 版次
// PrintTime string `json:"print_time"` // 印刷时间
// FixPrice string `json:"fix_price"` // 定价
// BindingLayout string `json:"binding_layout"` // 装帧
// Format string `json:"format"` // 开本
// Paper string `json:"paper"` // 纸张
// Pages string `json:"pages"` // 页数
// Wordage string `json:"wordage"` // 字数
// Languages string `json:"languages"` // 语种
// Era string `json:"era"` // 年代
// EngravingMethod string `json:"engraving_method"` // 刻印方式
// Dimensions string `json:"dimensions"` // 尺寸
// VolumeNumber string `json:"volume_number"` // 册数
// BookPic string `json:"book_pic"` // 图书封面图(官图)
// BookPicS string `json:"book_pic_s"` // 图书封面图(实拍图)
// SellingPrice string `json:"selling_price"` // 售价
// Condition string `json:"condition"` // 品相
// ExpressDeliveryFee string `json:"express_delivery_fee"` // 快递费
// Editor string `json:"editor"` // 编辑
// Category string `json:"category"` // 分类
// BuyCount string `json:"buy_count"` // 买过
// SellCount string `json:"sell_count"` // 在卖
// Content string `json:"content"` // 内容
// Mid int64 `json:"mid"` // 商家id
// ItemId int64 `json:"item_id"` // 商品id
// ShopId int64 `json:"shop_id"` // 店铺id
// DetailUrl string `json:"detail_url"` // 商品详情url
//}
//
//// 获取图片URL(官图和拍图)
//func OutGetImageByIsbns(token string, isbn string, proxy string, isLiveImage int, isReturnMsg int) (*BookInfo, error) {
// fmt.Println("[DEBUG] 使用的ISBN: ", isbn)
// // isLiveImage 1实拍图 0官图 isReturnMsg 0商品信息
// bookInfo := &BookInfo{}
// //if isLiveImage == 0 {
// // 孔网官图请求
// gtUrl := fmt.Sprintf("%s?keyword=%s", "https://search.kongfz.com/pc-gw/search-web/client/pc/bookLib/keyword/list", isbn)
// // 创建HTTP客户端
// requestGt := gorequest.New()
// // 设置代理(如果有提供代理URL)
// if proxy != "" {
// requestGt.Proxy(proxy)
// }
// // 发送请求
// respGt, bodyGt, errsGt := requestGt.Get(gtUrl).
// Set("Cookie", fmt.Sprintf("PHPSESSID=%s", token)).
// Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36").
// Set("Accept", "application/json, text/plain, */*").
// Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8").
// Set("Referer", "https://item.kongfz.com/").
// Timeout(30 * time.Second).
// End()
// if len(errsGt) > 0 {
// // 检查是否是代理相关错误
// var isProxyError bool
// var errorDetails []string
// for _, e := range errsGt {
// errorStr := e.Error()
// errorDetails = append(errorDetails, errorStr)
// if strings.Contains(errorStr, "Proxy Authentication Required") ||
// strings.Contains(errorStr, "connectex: A connection attempt failed") ||
// strings.Contains(errorStr, "connectex: No connection could be made") ||
// strings.Contains(errorStr, "proxyconnect tcp") ||
// strings.Contains(errorStr, "timeout") ||
// strings.Contains(errorStr, "connection refused") {
// isProxyError = true
// }
// }
// log.Printf("[ERROR] 请求错误详情: %v", errorDetails)
// if isProxyError {
// // 处理代理失败
// return nil, fmt.Errorf("代理连接失败")
// }
// return nil, fmt.Errorf("查询请求失败: %v", errsGt)
// }
// //检查HTTP状态码
// if respGt.StatusCode != http.StatusOK {
// return nil, fmt.Errorf("HTTP错误: %s", respGt.Status)
// }
// // 解析响应
// var apiGtResp struct {
// Status int `json:"status"`
// ErrType string `json:"errType"`
// Message string `json:"message"`
// SystemTime int64 `json:"systemTime"`
// Data struct {
// ItemResponse struct {
// Total int `json:"total"`
// List []struct {
// BookName string `json:"bookName"`
// Mid int64 `json:"mid"`
// ImgUrlEntity struct {
// BigImgUrl string `json:"bigImgUrl"`
// } `json:"imgUrlEntity"`
// Isbn string `json:"isbn"`
// BookShowInfo []string `json:"bookShowInfo"`
// } `json:"list"`
// } `json:"itemResponse"`
// } `json:"data"`
// }
// if err := json.Unmarshal([]byte(bodyGt), &apiGtResp); err != nil {
// return nil, fmt.Errorf("解析JSON失败: %w", err)
// }
// if apiGtResp.ErrType == "102" {
// return nil, fmt.Errorf("错误信息: %w状态码: %s", apiGtResp.Message, apiGtResp.ErrType)
// }
// // 如果找到条目返回图片URL
// if apiGtResp.Data.ItemResponse.Total > 0 && len(apiGtResp.Data.ItemResponse.List) > 0 {
// list := apiGtResp.Data.ItemResponse.List[0]
// bookShowInfo := list.BookShowInfo
// bookInfo.BookName = list.BookName
// bookInfo.BookPic = list.ImgUrlEntity.BigImgUrl
// bookInfo.ISBN = list.Isbn
// // 根据长度安全填充字段
// if isReturnMsg == 0 {
// if len(bookShowInfo) > 0 {
// bookInfo.Author = bookShowInfo[0]
// }
// if len(bookShowInfo) > 1 {
// bookInfo.Publisher = bookShowInfo[1]
// }
// if len(bookShowInfo) > 2 {
// bookInfo.PublicationTime = validateDateFormat(bookShowInfo[2])
// }
// if len(bookShowInfo) > 3 {
// bookInfo.BindingLayout = bookShowInfo[3]
// }
// if len(bookShowInfo) > 4 {
// bookInfo.FixPrice = bookShowInfo[4]
// } else {
// log.Printf("[WARN] BookShowInfo 长度不足 (仅 %d 项): %v", len(bookShowInfo), bookShowInfo)
// }
// }
// }
// //return bookInfo, nil
//
// //}
// //if isLiveImage == 1 {
//
// size := 10
// // 实拍图
// sptUrl := fmt.Sprintf("%s?dataType=0&keyword=%s&page=1&size=%d&sortType=7&actionPath=quality,sortType&quality=85~&quaSelect=2&userArea=13003000000",
// "https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/list", isbn, size)
// //创建HTTP客户端
// requestSpt := gorequest.New()
// //设置代理(如果有提供代理URL)
// if proxy != "" {
// requestSpt.Proxy(proxy)
// }
// // 发送请求
// respSpt, bodySpt, errsSpt := requestSpt.Get(sptUrl).
// Proxy(proxy).
// Set("Cookie", token).
// Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36").
// Set("Accept", "application/json, text/plain, */*").
// Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8").
// Set("Referer", "https://item.kongfz.com/").
// Timeout(30 * time.Second).
// End()
// // 错误处理
// if len(errsSpt) > 0 {
// return nil, fmt.Errorf("请求失败: %v", errsSpt)
// }
// // 检查HTTP状态码
// if respSpt.StatusCode != http.StatusOK {
// return nil, fmt.Errorf("HTTP错误: %s", respSpt.Status)
// }
// // 解析响应
// var apiSptResp struct {
// Status int `json:"status"`
// ErrType string `json:"errType"`
// Message string `json:"message"`
// SystemTime int64 `json:"systemTime"`
// Data struct {
// ItemResponse struct {
// Total int `json:"total"`
// List []struct {
// ItemId int64 `json:"itemId"`
// Title string `json:"title"`
// ImgUrl string `json:"imgUrl"`
// ImgBigUrl string `json:"imgBigUrl"`
// Author string `json:"author"`
// PubDateText string `json:"pubDateText"`
// Isbn string `json:"isbn"`
// Press string `json:"press"`
// ShopId int64 `json:"shopId"`
// TplRecords []struct {
// Key string `json:"key"`
// Value string `json:"value"`
// } `json:"tplRecords"`
// } `json:"list"`
// } `json:"itemResponse"`
// } `json:"data"`
// }
// // 解析JSON
// if err := json.Unmarshal([]byte(bodySpt), &apiSptResp); err != nil {
// return nil, fmt.Errorf("解析JSON失败: %w", err)
// }
// if apiSptResp.ErrType == "102" {
// return nil, fmt.Errorf("错误信息: %w状态码: %s", apiSptResp.Message, apiSptResp.ErrType)
// }
// if apiSptResp.Data.ItemResponse.Total > 0 && len(apiSptResp.Data.ItemResponse.List) > 0 {
// // 确定其实索引
// var startIndex int
// if size >= apiSptResp.Data.ItemResponse.Total {
// startIndex = apiSptResp.Data.ItemResponse.Total - 1
// } else {
// startIndex = size - 1
// }
// for attempt := 0; attempt < 3; attempt++ {
// currentIndex := startIndex - attempt
// // 检查索引是否有效
// if currentIndex < 0 || currentIndex >= len(apiSptResp.Data.ItemResponse.List) {
// log.Printf("[DEBUG] 索引 %d 超出范围,跳过", currentIndex)
// continue
// }
// randomNum := rand.Intn(currentIndex + 1)
// item := apiSptResp.Data.ItemResponse.List[randomNum]
// // 检查图片URL是否存在
// if item.ImgBigUrl == "" {
// log.Printf("[DEBUG] 索引 %d 的图片URL为空跳过", randomNum)
// continue
// }
// // 响应信息
// bookInfo.BookPicS = item.ImgUrl
// bookInfo.ISBN = item.Isbn
// if bookInfo.BookName == "" {
// bookInfo.BookName = item.Title
// if isReturnMsg == 0 {
// // 安全地获取TplRecords中的值
// if len(item.TplRecords) > 0 {
// bookInfo.Author = item.TplRecords[0].Value
// }
// if len(item.TplRecords) > 1 {
// bookInfo.Publisher = item.TplRecords[1].Value
// }
// if len(item.TplRecords) > 2 {
// bookInfo.PublicationTime = validateDateFormat(item.TplRecords[2].Value)
// }
// if len(item.TplRecords) > 3 {
// bookInfo.BindingLayout = item.TplRecords[3].Value
// }
// }
// }
// return bookInfo, nil
// }
// //}
// }
// return nil, fmt.Errorf("查询失败,没有数据!")
//}
//
//// 验证日期格式
//func validateDateFormat(dateStr string) int64 {
// // 去除前后空格
// dateStr = strings.TrimSpace(dateStr)
//
// // 替换各种分隔符为统一的分隔符"-"
// dateStr = regexp.MustCompile(`[/_\\.,\s]+`).ReplaceAllString(dateStr, "-")
//
// // 处理纯年份格式 (4位数字)
// if regexp.MustCompile(`^\d{4}$`).MatchString(dateStr) {
// dateStr += "-01-01"
// }
//
// // 处理年月格式 (4位数字-1或2位数字)
// if matches := regexp.MustCompile(`^(\d{4})-(\d{1,2})$`).FindStringSubmatch(dateStr); len(matches) == 3 {
// year := matches[1]
// month := matches[2]
// if len(month) == 1 {
// month = "0" + month
// }
// if monthNum, _ := strconv.Atoi(month); monthNum >= 1 && monthNum <= 12 {
// dateStr = year + "-" + month + "-01"
// } else {
// return 0
// }
// }
//
// // 处理年月日格式 (4位数字-1或2位数字-1或2位数字)
// if matches := regexp.MustCompile(`^(\d{4})-(\d{1,2})-(\d{1,2})`).FindStringSubmatch(dateStr); len(matches) >= 4 {
// year := matches[1]
// month := matches[2]
// day := matches[3]
//
// // 标准化月份和日期为两位数
// if len(month) == 1 {
// month = "0" + month
// }
// if len(day) == 1 {
// day = "0" + day
// }
//
// dateStr = year + "-" + month + "-" + day
// }
//
// // 加载上海时区
// loc, err := time.LoadLocation("Asia/Shanghai")
// if err != nil {
// // 如果加载时区失败使用UTC+8作为后备方案
// loc = time.FixedZone("CST", 8*60*60)
// }
//
// // 尝试解析为标准日期格式,并指定上海时区
// parsedTime, err := time.ParseInLocation("2006-01-02", dateStr, loc)
// if err != nil {
// return 0
// }
//
// // 返回秒级时间戳UTC时间但解析时已经考虑了时区偏移
// return parsedTime.Unix()
//}
//
//// 代理类型常量
//const (
// CalfElephantProxyType = "CALF_ELEPHANT_PROXY"
// TailProxyType = "TAIL_PROXY"
//)
//
//// 代理服务器列表
//var (
// servers = []string{
// "http-dynamic.xiaoxiangdaili.com",
// "http-dynamic-S02.xiaoxiangdaili.com",
// "http-dynamic-S03.xiaoxiangdaili.com",
// "http-dynamic-S04.xiaoxiangdaili.com",
// }
// randMutex sync.Mutex
// globalRand *rand.Rand
//
// // 代理健康状态管理
// proxyHealthMaps = make(map[string]*ProxyHealth)
// proxyHealthMutex sync.RWMutex
//)
//
//// ProxyManager 代理管理器结构体
//type ProxyManager struct {
// servers []string `json:"servers"` // 代理服务器列表
// username string `json:"username"` // 代理账号
// password string `json:"password"` // 代理密码
// tailCardSecret string `json:"tail_card_secret"` // 尾巴代理卡密
// proxyType string `json:"proxy_type"` // 代理类型 CALF_ELEPHANT_PROXY/TAIL_PROXY
//}
//
//// 代理健康状态
//type ProxyHealth struct {
// SuccessCount int // 成功次数
// FailCount int // 失败次数
// LastCheck time.Time // 最后检查时间
// ResponseTime time.Duration // 响应时间
// IsHealthy bool // 是否健康
//}
//
//func init() {
// // 创建全局的随机数生成器
// globalRand = rand.New(rand.NewSource(time.Now().UnixNano()))
//}
//
//// 获取代理URL
//func proxyTypeManager(proxyType, username, password, machineCode string) (string, error) {
// switch proxyType {
// case CalfElephantProxyType:
// return buildCalfElephantProxyURL(username, password)
// case TailProxyType:
// return buildTailProxyURL(machineCode)
// default:
// return "", fmt.Errorf("不支持的代理类型: %s", proxyType)
// }
//}
//
//// 构建小象代理URL
//func buildCalfElephantProxyURL(username, password string) (string, error) {
// server := randomServer()
// proxyURL := fmt.Sprintf("http://%s:%s@%s:%d",
// url.QueryEscape(username),
// url.QueryEscape(password),
// server,
// 10030)
//
// // 检测代理可用性
// if err := checkProxyHealth(proxyURL); err != nil {
// log.Printf("[WARN] 代理 %s 检测失败: %v", server, err)
// // 尝试下一个代理服务器
// return tryNextCalfElephantProxy(username, password, server)
// }
//
// log.Printf("[INFO] 使用小象代理: %s", server)
// return proxyURL, nil
//}
//
//// 尝试下一个小象代理服务器
//func tryNextCalfElephantProxy(username, password, failedServer string) (string, error) {
// // 创建服务器副本并排除失败的服务器
// availableServers := make([]string, 0)
// for _, server := range servers {
// if server != failedServer {
// availableServers = append(availableServers, server)
// }
// }
//
// if len(availableServers) == 0 {
// return "", fmt.Errorf("所有小象代理服务器都不可用")
// }
//
// // 随机尝试可用服务器
// for _, server := range shuffleServers(availableServers) {
// proxyURL := fmt.Sprintf("http://%s:%s@%s:%d",
// url.QueryEscape(username),
// url.QueryEscape(password),
// server,
// 10030)
//
// if err := checkProxyHealth(proxyURL); err == nil {
// log.Printf("[INFO] 切换到可用代理: %s", server)
// return proxyURL, nil
// }
// log.Printf("[WARN] 代理 %s 检测失败", server)
// }
//
// return "", fmt.Errorf("所有可用的小象代理服务器都检测失败")
//}
//
//// 构建内置代理URL
//func buildTailProxyURL(machineCode string) (string, error) {
// proxies, err := getProxies(machineCode)
// if err != nil {
// return "", err
// }
// if len(proxies) == 0 {
// return "", fmt.Errorf("未获取到有效代理")
// }
//
// // 过滤并选择健康的代理
// healthyProxies := filterHealthyProxies(proxies)
// if len(healthyProxies) > 0 {
// proxyURL := "http://" + randomElement(healthyProxies)
// log.Printf("[INFO] 使用健康尾巴代理: %s", proxyURL)
// return proxyURL, nil
// }
//
// // 如果没有健康代理,检测所有代理
// log.Printf("[INFO] 未找到健康代理,开始检测代理可用性...")
// return findWorkingTailProxy(proxies)
//}
//
//// 获取代理服务器列表
//func getProxies(machineCode string) ([]string, error) {
// log.Printf("[INFO] 开始获取代理列表: %s", machineCode)
// // 生成签名
// sign := fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("9999%s9999", machineCode))))
//
// GetProxiesUrl := fmt.Sprintf("http://114.66.2.223:7842/api/proxies/get_proxy?machine_code=%s&sign=%s&agent_id=9999",
// machineCode, sign)
//
// req := gorequest.New().Get(GetProxiesUrl).Timeout(20 * time.Second)
// _, body, errs := req.End()
// if len(errs) > 0 {
// return nil, fmt.Errorf("获取代理失败: %v", errs)
// }
//
// // 检查是否为JSON错误响应
// if strings.HasPrefix(strings.TrimSpace(body), "{") && strings.HasSuffix(strings.TrimSpace(body), "}") {
// // 尝试解析为JSON错误响应
// var errorResp struct {
// Code int `json:"code"`
// Message string `json:"message"`
// }
// if err := json.Unmarshal([]byte(body), &errorResp); err == nil {
// return nil, fmt.Errorf("获取代理失败: %s (错误码: %d)", errorResp.Message, errorResp.Code)
// }
// }
//
// // 解析响应
// lines := strings.Split(strings.TrimSpace(body), "\n")
// var proxies []string
// for _, line := range lines {
// line = strings.TrimSpace(line)
// if line != "" && !strings.HasPrefix(line, "{") {
// proxies = append(proxies, line)
// }
// }
// if len(proxies) == 0 {
// return nil, fmt.Errorf("未获取到有效代理")
// }
//
// log.Printf("[INFO] 获取到 %d 个代理", len(proxies))
// return proxies, nil
//}
//
//// 过滤健康代理
//func filterHealthyProxies(proxies []string) []string {
// proxyHealthMutex.RLock()
// defer proxyHealthMutex.RUnlock()
//
// var healthy []string
// for _, proxy := range proxies {
// if health, exists := proxyHealthMaps[proxy]; exists && health.IsHealthy {
// // 检查是否在最近检查过5分钟内
// if time.Since(health.LastCheck) < 5*time.Minute {
// healthy = append(healthy, proxy)
// }
// }
// }
// return healthy
//}
//
//// 查找可用的尾巴代理
//func findWorkingTailProxy(proxies []string) (string, error) {
// // 打乱代理顺序
// shuffledProxies := shuffleServers(proxies)
//
// // 并发检测代理
// type proxyResult struct {
// proxy string
// err error
// }
//
// ch := make(chan proxyResult, len(shuffledProxies))
// var wg sync.WaitGroup
//
// // 限制并发数
// sem := make(chan struct{}, 5)
//
// for _, proxy := range shuffledProxies {
// wg.Add(1)
// go func(p string) {
// defer wg.Done()
// sem <- struct{}{}
// defer func() { <-sem }()
//
// proxyURL := "http://" + p
// err := checkProxyHealth(proxyURL)
// ch <- proxyResult{proxy: p, err: err}
// }(proxy)
// }
//
// wg.Wait()
// close(ch)
//
// // 收集结果
// var workingProxies []string
// for result := range ch {
// if result.err == nil {
// workingProxies = append(workingProxies, result.proxy)
// // 更新健康状态
// updateProxyHealth(result.proxy, true, 0)
// } else {
// updateProxyHealth(result.proxy, false, 0)
// }
// }
//
// if len(workingProxies) > 0 {
// selected := randomElement(workingProxies)
// log.Printf("[INFO] 找到可用代理: %s (共 %d 个可用)", selected, len(workingProxies))
// return "http://" + selected, nil
// }
//
// return "", fmt.Errorf("所有尾巴代理都不可用")
//}
//
//// 检测代理健康状态
//func checkProxyHealth(proxyURL string) error {
// start := time.Now()
//
// req := gorequest.New().Proxy(proxyURL).Timeout(10 * time.Second)
// resp, _, errs := req.Get("https://shop.kongfz.com/").End()
//
// responseTime := time.Since(start)
//
// if len(errs) > 0 {
// updateProxyHealth(proxyURL, false, responseTime)
// return fmt.Errorf("代理连接失败: %v", errs)
// }
//
// if resp.StatusCode != 200 {
// updateProxyHealth(proxyURL, false, responseTime)
// return fmt.Errorf("代理响应状态码错误: %d", resp.StatusCode)
// }
//
// updateProxyHealth(proxyURL, true, responseTime)
// log.Printf("[DEBUG] 代理 %s 检测成功, 响应时间: %v", getProxyHost(proxyURL), responseTime)
// return nil
//}
//
//// 更新代理健康状态
//func updateProxyHealth(proxyURL string, success bool, responseTime time.Duration) {
// proxyHealthMutex.Lock()
// defer proxyHealthMutex.Unlock()
//
// host := getProxyHost(proxyURL)
// if _, exists := proxyHealthMaps[host]; !exists {
// proxyHealthMaps[host] = &ProxyHealth{}
// }
//
// health := proxyHealthMaps[host]
// health.LastCheck = time.Now()
//
// if success {
// health.SuccessCount++
// health.FailCount = 0
// health.ResponseTime = responseTime
// health.IsHealthy = true
// } else {
// health.FailCount++
// health.SuccessCount = 0
// // 连续失败3次标记为不健康
// if health.FailCount >= 3 {
// health.IsHealthy = false
// }
// }
//}
//
//// 获取代理主机名
//func getProxyHost(proxyURL string) string {
// if strings.HasPrefix(proxyURL, "http://") {
// proxyURL = proxyURL[7:]
// }
// // 去除认证信息
// if atIndex := strings.Index(proxyURL, "@"); atIndex != -1 {
// proxyURL = proxyURL[atIndex+1:]
// }
// // 去除端口
// if colonIndex := strings.Index(proxyURL, ":"); colonIndex != -1 {
// proxyURL = proxyURL[:colonIndex]
// }
// return proxyURL
//}
//
//// 随机代理服务器
//func randomServer() string {
// return randomElement(servers)
//}
//
//// 线程安全的随机元素选择
//func randomElement(slice []string) string {
// randMutex.Lock()
// defer randMutex.Unlock()
// return slice[globalRand.Intn(len(slice))]
//}
//
//// 打乱服务器顺序
//func shuffleServers(servers []string) []string {
// randMutex.Lock()
// defer randMutex.Unlock()
//
// shuffled := make([]string, len(servers))
// copy(shuffled, servers)
// globalRand.Shuffle(len(shuffled), func(i, j int) {
// shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
// })
// return shuffled
//}