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 //}