package main ///* //#cgo LDFLAGS: -ldl // //#include //#include //#include //*/ //import "C" //import ( // "context" // "database/sql" // "encoding/json" // "fmt" // "io" // "log" // "math/rand" // "net/http" // "net/url" // "os" // "path/filepath" // "regexp" // "strconv" // "strings" // "sync" // "time" // "unsafe" // // "github.com/PuerkitoBio/goquery" // "github.com/chromedp/chromedp" // _ "github.com/go-sql-driver/mysql" // "github.com/parnurzeal/gorequest" //) // //const ( // UseProxy = "proxy" // 使用代理 // NotProxy = "direct" // 不用代理代理 //) // //type Config struct { // App struct { // MaxRetryTimes int `ini:"app.max_retry_times" json:"max_retry_times" default:"3"` // RateLimitDelay time.Duration `ini:"app.rate_limit_delay" json:"rate_limit_delay" default:"500ms"` // Size int `ini:"app.size" json:"size" default:"5"` // DefaultUserAgent string `ini:"app.default_user_agent" json:"default_user_agent" default:"Mozilla/5.0"` // } `ini:"app" json:"app"` // // API struct { // LoginURL string `ini:"api.login_url" json:"login_url" default:"https://login.kongfz.com/Pc/Login/account"` // BookSearchURL string `ini:"api.book_search_url" json:"book_search_url" default:"https://search.kongfz.com/pc-gw/search-web/client/pc/bookLib/keyword/list"` // ProductSearchURL string `ini:"api.product_search_url" json:"product_search_url" default:"https://search.kongfz.com/pc-gw/search-web/client/pc/product/keyword/list"` // } `ini:"api" json:"api"` // // Proxy struct { // Servers string `ini:"proxy.servers" json:"servers" default:"http-dynamic.xiaoxiangdaili.com,http-dynamic-S02.xiaoxiangdaili.com,http-dynamic-S03.xiaoxiangdaili.com,http-dynamic-S04.xiaoxiangdaili.com"` // Username string `ini:"proxy.username" json:"username" default:"1297757178467602432"` // Password string `ini:"proxy.password" json:"password" default:"QgQBvP7f"` // TailMachineCode string `ini:"proxy.tail_machine_code" json:"tail_machine_code" default:"b7bf22a237ec692f13fcc2c43ee63252"` // TailCardKey string `ini:"proxy.tail_card_key" json:"tail_card_key" default:"DL_20_YK_1920acb2129844c2aabade3896560a9b"` // ProxyFilePath string `ini:"proxy.proxy_file_path" json:"proxy_file_path" default:"dll/proxyConfig.dll"` // } `ini:"proxy" json:"proxy"` // // Database struct { // Username string `ini:"database.username" json:"username" default:"newAdmin"` // Password string `ini:"database.password" json:"password" default:"bYPp8SbBe5F7nz2i"` // Host string `ini:"database.host" json:"host" default:"146.56.227.42:3306"` // Name string `ini:"database.name" json:"name" default:"newadmin"` // } `ini:"database" json:"database"` //} // //// 条目详情结构体 //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 //} // //// API响应结构 //type APIResp struct { // Success bool `json:"success"` // Message string `json:"message,omitempty"` // GoodsNum string `json:"goods_num,omitempty"` // PNum string `json:"pnum,omitempty"` // Data interface{} `json:"data,omitempty"` // Error string `json:"error,omitempty"` //} // //// APIResponse //type APIResponse struct { // Success bool `json:"success"` // Message string `json:"message,omitempty"` // Data interface{} `json:"data,omitempty"` //} // //// 账号凭证结构 //type AccountCredential struct { // ID int64 // Username string // Password string // Token string //} // //// 全局变量 //var ( // cf Config // 配置信息 // tailProxyMu sync.Mutex // 互斥锁 // proxyFailCount int // mu sync.RWMutex // 数据库锁 // // // 全局代理管理器 // globalProxyManager *ProxyConfigManager // proxyManagerOnce sync.Once // proxyManagerInitErr error //) // //// ProductInfo 商品信息结构 //type ProductInfo struct { // ItemID string `json:"itemId"` // BookName string `json:"bookName"` // Price string `json:"price"` // ShippingFee string `json:"shippingFee"` //} // //// ProductResponse 响应结构 //type ProductResponse struct { // Success bool `json:"success"` // Message string `json:"message,omitempty"` // Data []ProductInfo `json:"data,omitempty"` //} // //// 并行获取详情的结果结构 //type DetailResult struct { // URL string // Doc *goquery.Document // Error error // Index int //} // //// 第一阶段:收集基本信息并识别需要详情的项目 //type BookItem struct { // Book BookInfo // Selection *goquery.Selection // HasDetail bool // DetailURL string // Index int //} // //// 分类项结构体 //type SalesCategory struct { // Key string `json:"key"` // Value int `json:"value"` //} // //// 图书详情响应结构体 //type BookDetailResponse struct { // Status bool `json:"status"` // Result BookList `json:"result"` // ErrMessage string `json:"errMessage"` // ErrCode int `json:"errCode"` //} // //// 图书列表结构体 //type BookList struct { // Current int `json:"current"` // Data []BookInformation `json:"data"` // Total int `json:"total"` //} // //// 图书信息结构体 //type BookInformation struct { // Author string `json:"author"` // BookName string `json:"bookName"` // ContentIntroduction string `json:"contentIntroduction"` // ImgUrl string `json:"imgUrl"` // Isbn string `json:"isbn"` // ItemUrls ItemUrls `json:"itemUrls"` // Mid int `json:"mid"` // NewMinPrice string `json:"newMinPrice"` // OldMinPrice string `json:"oldMinPrice"` // Press string `json:"press"` // Price string `json:"price"` // PubDate string `json:"pubDate"` // RiseTag string `json:"riseTag"` // AuthorArr []AuthorInfo `json:"authorArr"` // PressUrl string `json:"pressUrl"` //} // //// 作者信息结构体 //type AuthorInfo struct { // Name string `json:"name"` // OriName string `json:"oriName"` // Nationality string `json:"nationality"` // Role string `json:"role"` // Url string `json:"url"` //} // //// 商品链接结构体 //type ItemUrls struct { // AppUrl string `json:"appUrl"` // MUrl string `json:"mUrl"` // MiniUrl string `json:"miniUrl"` // PcUrl string `json:"pcUrl"` //} // //type UserInfo struct { // UserID int64 `json:"userId"` // Nickname string `json:"nickname"` // Mobile string `json:"mobile"` //} // //// 店铺快递费参数 //type ParamsInfo struct { // Params []Param `json:"params"` // Area string `json:"area"` //} // //type Param struct { // UserId string `json:"userId"` // ItemId string `json:"itemId"` //} // //// ProxyConfigManager 代理配置SO管理器 //type ProxyConfigManager struct { // handle unsafe.Pointer //} // //func NewProxyConfigManager(soPath string) (*ProxyConfigManager, error) { // cSoPath := C.CString(soPath) // defer C.free(unsafe.Pointer(cSoPath)) // // handle := C.dlopen(cSoPath, C.RTLD_LAZY) // if handle == nil { // err := C.dlerror() // if err != nil { // return nil, fmt.Errorf("加载代理配置SO失败: %s", C.GoString(err)) // } // return nil, fmt.Errorf("加载代理配置SO失败: 未知错误") // } // return &ProxyConfigManager{handle: handle}, nil //} // //func (m *ProxyConfigManager) Close() { // if m.handle != nil { // C.dlclose(m.handle) // m.handle = nil // } //} // //// ProxyTypeManager 调用代理类型管理器 //func (m *ProxyConfigManager) ProxyTypeManager(proxyType, username, password, machineCode string) (string, error) { // // 查找 ProxyTypeManager 函数 // cFuncName := C.CString("ProxyTypeManager") // defer C.free(unsafe.Pointer(cFuncName)) // // proc := C.dlsym(m.handle, cFuncName) // if proc == nil { // err := C.dlerror() // if err != nil { // return "", fmt.Errorf("找不到函数 ProxyTypeManager: %s", C.GoString(err)) // } // return "", fmt.Errorf("找不到函数 ProxyTypeManager") // } // // // 准备参数 // cProxyType := C.CString(proxyType) // cUsername := C.CString(username) // cPassword := C.CString(password) // cMachineCode := C.CString(machineCode) // defer func() { // C.free(unsafe.Pointer(cProxyType)) // C.free(unsafe.Pointer(cUsername)) // C.free(unsafe.Pointer(cPassword)) // C.free(unsafe.Pointer(cMachineCode)) // }() // // // 定义函数类型 // type ProxyTypeManagerFunc func(proxyType, username, password, machineCode *C.char) *C.char // // // 转换函数指针 // proxyFunc := *(*ProxyTypeManagerFunc)(unsafe.Pointer(&proc)) // // // 调用函数 // result := proxyFunc(cProxyType, cUsername, cPassword, cMachineCode) // if result == nil { // return "", fmt.Errorf("ProxyTypeManager 返回空结果") // } // // goResult := C.GoString(result) // // // 查找并调用 FreeCString 函数 // cFreeName := C.CString("FreeCString") // defer C.free(unsafe.Pointer(cFreeName)) // // freeProc := C.dlsym(m.handle, cFreeName) // if freeProc != nil { // type FreeCStringFunc func(str *C.char) // freeFunc := *(*FreeCStringFunc)(unsafe.Pointer(&freeProc)) // freeFunc(result) // } else { // // 如果找不到 FreeCString,使用 C.free // C.free(unsafe.Pointer(result)) // } // // return goResult, nil //} // //// 登录 //func outLogin(username, password string) (string, error) { // if username == "" || password == "" { // return "", fmt.Errorf("请输入用户名和密码!") // } // formData := map[string]string{ // "loginName": username, // "loginPass": password, // "returnUrl": "http://user.kongfz.com/", // } // resp, body, errs := gorequest.New(). // Post(cf.API.LoginURL). // Set("Content-Type", "application/x-www-form-urlencoded"). // Set("User-Agent", cf.App.DefaultUserAgent). // Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"). // Send(formData). // Timeout(15 * time.Second).End() // if len(errs) > 0 { // return "", fmt.Errorf("登录请求失败: %v", errs) // } // // 检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return "", fmt.Errorf("登录失败(HTTP状态码: %d)", resp.StatusCode) // } // // 提取Cookie // cookie := resp.Header.Get("Set-Cookie") // if strings.Contains(body, "window.location.href='https://login.kongfz.cn/Pc/Session/rsync") { // if cookie == "" { // return "", fmt.Errorf("登录成功但未获取到Cookie") // } // // 登录成功 // if strings.Contains(cookie, "PHPSESSID=") { // token := strings.Split(strings.Split(cookie, "PHPSESSID=")[1], ";")[0] // return token, nil // } // return "", fmt.Errorf("登录失败: 未找到PHPSESSID") // } // // 错误信息 // var res struct { // Status bool `json:"status"` // ErrCode int `json:"errCode"` // ErrInfo string `json:"errInfo"` // } // if err := json.Unmarshal([]byte(body), &res); err == nil { // if res.ErrCode == 1001 || res.ErrCode == 1005 { // return "", fmt.Errorf("账号或密码错误!") // } // if res.ErrInfo != "" { // return "", fmt.Errorf("登录失败: %s", res.ErrInfo) // } // } // return "", fmt.Errorf("登录失败,未知错误!") //} // //// 获取用户信息(带有Out的都非官方标准接口) //func outGetUserMsg(token string) (*UserInfo, error) { // url := "https://user.kongfz.com/User/Index/getUserInfo/" // resp, body, errs := gorequest.New(). // 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"). // Timeout(15 * time.Second). // End() // if len(errs) > 0 { // return nil, fmt.Errorf("查询请求失败: %v", errs) // } // //检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", resp.Status) // } // var userInfo struct { // Status bool `json:"status"` // Data struct { // UserID int64 `json:"userId"` // Nickname string `json:"nickname"` // Mobile string `json:"mobile"` // } // } // if err := json.Unmarshal([]byte(body), &userInfo); err != nil { // return nil, fmt.Errorf("解析JSON失败: %w", err) // } // user := &UserInfo{} // if !userInfo.Status { // return nil, fmt.Errorf("获取用户失败!") // } // user.UserID = userInfo.Data.UserID // user.Nickname = userInfo.Data.Nickname // user.Mobile = userInfo.Data.Mobile // return user, nil //} // //// 获取商品模版 //func outGetGoodsTplMsg(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()) // // 创建HTTP客户端 // request := gorequest.New() // // 设置代理(如果有提供代理URL) // if proxy != "" { // request.Proxy(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(15 * time.Second). // End() // if errs != nil { // // 检查是否是代理相关错误 // var isProxyError bool // var errorDetails []string // for _, e := range errs { // 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", errs) // } // //检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", resp.Status) // } // var data map[string]interface{} // if err := json.Unmarshal([]byte(body), &data); err != nil { // return nil, fmt.Errorf("解析JSON失败: %w", err) // } // if val, ok := data["status"].(float64); ok && val == 1 { // return data, nil // } // return nil, fmt.Errorf("API返回错误: %+v", data) //} // //// 获取商品列表 //func outGetGoodsListMsgFromSelfShop(token string, proxy string, itemSn string, priceMin string, priceMax string, startCreateTime int, // endCreateTime int, requestType string, isItemSnEqual int, page int, size int) (map[string]interface{}, error) { // if token == "" { // return nil, fmt.Errorf("请先登录获取Token") // } // url := "https://seller.kongfz.com/pc-gw/book-manage-service/client/pc/goods/unSold/list" // formData := struct { // ItemSn string `json:"itemSn"` // PriceMin string `json:"priceMin"` // PriceMax string `json:"priceMax"` // StartCreateTime int `json:"startCreateTime"` // EndCreateTime int `json:"endCreateTime"` // RequestType string `json:"requestType,omitempty"` // IsItemSnEqual int `json:"isItemSnEqual,omitempty"` // Page int `json:"page,omitempty"` // Size int `json:"size,omitempty"` // }{ // ItemSn: itemSn, // PriceMin: priceMin, // PriceMax: priceMax, // StartCreateTime: startCreateTime, // EndCreateTime: endCreateTime, // RequestType: requestType, // IsItemSnEqual: isItemSnEqual, // Page: page, // Size: size, // } // request := gorequest.New() // if proxy != "" { // request.Proxy(proxy) // } // resp, body, errs := request.Post(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, */*"). // Send(formData). // Timeout(15 * time.Second). // End() // if errs != nil { // // 检查是否是代理相关错误 // var isProxyError bool // var errorDetails []string // for _, e := range errs { // 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", errs) // } // //检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", resp.Status) // } // var data map[string]interface{} // if err := json.Unmarshal([]byte(body), &data); err != nil { // return nil, fmt.Errorf("解析JSON失败: %w", err) // } // if _, ok := data["status"]; ok { // return data, nil // } // return nil, fmt.Errorf("API返回错误: %+v", data) //} // //// 删除商品-已登的店铺(带有Out的都非官方标准接口) //func outDelGoodsFromSelfShop(token, proxy, itemId string) (map[string]interface{}, error) { // if token == "" { // return nil, fmt.Errorf("请先登录获取Token") // } // url := "https://seller.kongfz.com/pc-gw/book-manage-service/client/pc/goods/quickUpdate" // formData := map[string]string{ // "itemId": itemId, // "updateType": "delete", // "value": "1", // } // request := gorequest.New() // if proxy != "" { // request.Proxy(proxy) // } // resp, body, errs := request.Post(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, */*"). // Send(formData). // Timeout(15 * time.Second). // End() // if errs != nil { // // 检查是否是代理相关错误 // var isProxyError bool // var errorDetails []string // for _, e := range errs { // 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", errs) // } // //检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", resp.Status) // } // var data map[string]interface{} // if err := json.Unmarshal([]byte(body), &data); err != nil { // return nil, fmt.Errorf("解析JSON失败: %w", err) // } // if status, ok := data["status"].(bool); ok && status { // return data, nil // } // if status, ok := data["status"].(float64); ok && status == 1 { // return data, nil // } // return nil, fmt.Errorf("API返回错误: %+v", data) //} // //// 新增商品(带有Out的都非官方标准接口) //func outAddGoods(token, proxy, formData string) (map[string]interface{}, error) { // if token == "" { // return nil, fmt.Errorf("请先登录获取Token") // } // url := "https://seller.kongfz.com/pc/itemInfo/add" // request := gorequest.New() // if proxy != "" { // request.Proxy(proxy) // } // resp, body, errs := request.Post(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, */*"). // Send(formData). // Timeout(15 * time.Second). // End() // if errs != nil { // // 检查是否是代理相关错误 // var isProxyError bool // var errorDetails []string // for _, e := range errs { // 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", errs) // } // //检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", resp.Status) // } // var data map[string]interface{} // if err := json.Unmarshal([]byte(body), &data); err != nil { // return nil, fmt.Errorf("解析JSON失败: %w", err) // } // if val, ok := data["status"]; ok && val == 1 { // return data, nil // } // return nil, fmt.Errorf("API返回错误: %+v", data) //} // //// 获取图片URL(官图和拍图)带有店铺过滤 //func outGetImageFilterShopId(token string, isbn string, shopId int, proxy string, isLiveImage int, isReturnMsg int) (map[string]string, error) { // fmt.Println("[DEBUG] 使用的ISBN: ", isbn) // if isLiveImage == 0 { // gtUrl := fmt.Sprintf("%s?keyword=%s", cf.API.BookSearchURL, isbn) // request := gorequest.New() // if proxy != "" { // request.Proxy(proxy) // } // resp, body, errs := request.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(errs) > 0 { // // 检查是否是代理相关错误 // var isProxyError bool // var errorDetails []string // for _, e := range errs { // 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", errs) // } // //检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", resp.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(body), &apiGtResp); err != nil { // return nil, fmt.Errorf("解析JSON失败: %w", err) // } // if apiGtResp.ErrType == "102" { // return nil, fmt.Errorf("错误信息: %w,状态码: %s", apiGtResp.Message, apiGtResp.ErrType) // } // var info map[string]string // // 如果找到条目,返回图片URL // if apiGtResp.Data.ItemResponse.Total > 0 && len(apiGtResp.Data.ItemResponse.List) > 0 { // list := apiGtResp.Data.ItemResponse.List[0] // info = map[string]string{ // "book_name": list.BookName, // "book_pic": list.ImgUrlEntity.BigImgUrl, // "isbn": list.Isbn, // } // } // return info, nil // } // if isLiveImage == 1 { // // 实拍图 // sptUrl := fmt.Sprintf("%s?dataType=0&keyword=%s&page=1&size=%d&sortType=7&actionPath=quality,sortType&quality=85~&quaSelect=2&userArea=13003000000", cf.API.ProductSearchURL, isbn, cf.App.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) // } // var info map[string]string // if apiSptResp.Data.ItemResponse.Total > 0 && len(apiSptResp.Data.ItemResponse.List) > 0 { // // 确定起始索引 // var startIndex int // if cf.App.Size >= apiSptResp.Data.ItemResponse.Total { // startIndex = apiSptResp.Data.ItemResponse.Total - 1 // } else { // startIndex = cf.App.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 // } // // 过滤店铺 // if item.ShopId == int64(shopId) { // log.Printf("[DEBUG] 索引 %d 的店铺ID需要过滤,跳过", randomNum) // continue // } // info = map[string]string{ // "book_name": item.Title, // "book_pic": item.ImgUrl, // "isbn": item.Isbn, // } // return info, nil // } // } // } // return nil, nil //} // //// 获取图片URL(官图和拍图) //func outGetImageByIsbn(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", cf.API.BookSearchURL, 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 { // // 实拍图 // sptUrl := fmt.Sprintf("%s?dataType=0&keyword=%s&page=1&size=%d&sortType=7&actionPath=quality,sortType&quality=85~&quaSelect=2&userArea=13003000000", cf.API.ProductSearchURL, isbn, cf.App.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 cf.App.Size >= apiSptResp.Data.ItemResponse.Total { // startIndex = apiSptResp.Data.ItemResponse.Total - 1 // } else { // startIndex = cf.App.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("查询失败,没有数据!") //} // //// 获取商品列表通过店铺ID //func outGetGoodsListMsgByShopId(shopId int, proxy string, retPrice int, isImage int, sortType string, sort string, priceMin float32, priceMax float32, pageNum, returnNum int) (books []BookInfo, goodsNum string, pNum string, err error) { // // 判断店铺ID // if shopId == 0 { // return nil, "", "", fmt.Errorf("店铺编码为空!") // } // // 判断是否有图片,设置默认值0 // var isImageStr string // if isImage == 0 { // isImageStr = "0" // } else { // isImageStr = "1" // } // // 判断一页图书数量,设置默认值100 // if returnNum == 0 { // returnNum = 100 // } // // 判断页数,设置默认值1 // if pageNum == 0 { // pageNum = 1 // } // // 判断排序类型,设置默认值sort // if sortType == "" { // sortType = "sort" // } else { // validSortTypes := map[string]bool{ // "sort": true, // "putDate": true, // "newItem": true, // "price": true, // } // if !validSortTypes[sortType] { // return nil, "", "", fmt.Errorf("无效的排序类型: %s,可选值: sort, putDate, newItem, price", sortType) // } // } // // 判断排序,设置默认值desc // if sort == "" { // sort = "desc" // } else { // validSorts := map[string]bool{ // "desc": true, // "asc": true, // } // if !validSorts[sort] { // return nil, "", "", fmt.Errorf("无效的排序类型: %s,可选值: desc, asc", sort) // } // } // var url string // var pMin int // pMin = 0 // var pMax int // pMax = 0 // // 判断价格下限,设置默认值0 // if priceMin == 0 && priceMax == 0 { // // 调用的url // url = fmt.Sprintf("https://shop.kongfz.com/%d/all/%s_%d_0_0_%d_%s_%s_%d_%d", // shopId, isImageStr, returnNum, pageNum, sortType, sort, pMin, pMax) // } else if priceMin == 0 { // url = fmt.Sprintf("https://shop.kongfz.com/%d/all/%s_%d_0_0_%d_%s_%s_%d_%.2f", // shopId, isImageStr, returnNum, pageNum, sortType, sort, pMin, priceMax) // } else if priceMax == 0 { // url = fmt.Sprintf("https://shop.kongfz.com/%d/all/%s_%d_0_0_%d_%s_%s_%.2f_%d", // shopId, isImageStr, returnNum, pageNum, sortType, sort, priceMin, pMax) // } else { // url = fmt.Sprintf("https://shop.kongfz.com/%d/all/%s_%d_0_0_%d_%s_%s_%.2f_%.2f", // shopId, isImageStr, returnNum, pageNum, sortType, sort, priceMin, priceMax) // } // // 发送请求 // response, err := fetchResponse(url, proxy) // if err != nil { // return nil, "", "", err // } // body, err := io.ReadAll(response.Body) // if err != nil { // return nil, "", "", err // } // doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(body))) // // 全部商品数量 // num := doc.Find("div.crumbs-nav-main.clearfix").Find("span") // if match := regexp.MustCompile(`\d+`).FindString(num.Text()); match != "" { // goodsNum = match // } // // 商品页数 // pg := doc.Find("li.pull-right.page_num").Find("span") // _, split, found := strings.Cut(strings.TrimSpace(pg.Text()), "/") // if found { // pNum = split // } else { // log.Printf("未找到页数!") // } // infoDiv := doc.Find("div.list-content") // var params ParamsInfo // if infoDiv.Length() > 0 { // item := infoDiv.Find("div.item.clearfix") // for i := 0; i < item.Length(); i++ { // s := item.Eq(i) // book := BookInfo{} // // 书名 // book.BookName = strings.TrimSpace(s.Find("div.title a.link").Text()) // // 提取ISBN // book.ISBN = strings.TrimSpace(s.AttrOr("isbn", "")) // // 店铺ID // shopid, _ := strconv.Atoi(strings.TrimSpace(s.AttrOr("shopid", ""))) // book.ShopId = int64(shopid) // // 商品ID // itemid, _ := strconv.Atoi(strings.TrimSpace(s.AttrOr("itemid", ""))) // book.ItemId = int64(itemid) // // 详情URL // book.DetailUrl = s.Find("div.item-img a.img-box").AttrOr("href", "") // // 价格 // if retPrice == 0 { // book.SellingPrice = s.Find("div.f_right.red.price").Find("span.bold").Text() // params.Params = append(params.Params, struct { // UserId string `json:"userId"` // ItemId string `json:"itemId"` // }{UserId: strings.TrimSpace(s.AttrOr("userid", "")), ItemId: strings.TrimSpace(s.AttrOr("itemid", ""))}) // } // books = append(books, book) // } // if params.Params != nil { // params.Area = "13003000000" // dataItem, err := getGoodsListShippingFee(params, proxy) // if err != nil { // return nil, "", "", err // } // for i := 0; i < len(books); i++ { // itemId := fmt.Sprintf("%d", books[i].ItemId) // for _, data := range dataItem { // if itemId == data.ItemID { // books[i].ExpressDeliveryFee = data.Fee[0].TotalFee // } // } // } // } // } // return books, goodsNum, pNum, nil //} // //// 定义对应的结构体 //type FeeInfo struct { // ShippingID string `json:"shippingId"` // ShippingName string `json:"shippingName"` // TotalFee string `json:"totalFee"` // ShippingText string `json:"shippingText"` // FilterTotalFee string `json:"filterTotalFee"` //} // //type DataItem struct { // Fee []FeeInfo `json:"fee"` // IsSeller bool `json:"isSeller"` // ItemID string `json:"itemId"` // UserID string `json:"userId"` //} // //type ResponseStruct struct { // Status bool `json:"status"` // Data []DataItem `json:"data"` // Message string `json:"message"` // ErrType string `json:"errType"` //} // //// 获取店铺里商品的快递费(定位到河南) //func getGoodsListShippingFee(params ParamsInfo, proxy string) ([]DataItem, error) { // if params.Params == nil { // return nil, fmt.Errorf("没有商品信息!") // } // paramsJSON, err := json.Marshal(params) // if err != nil { // return nil, fmt.Errorf("参数序列化失败: %v", err) // } // // URL 编码参数 // encodedParams := url.QueryEscape(string(paramsJSON)) // url := fmt.Sprintf("https://shop.kongfz.com/book/shopsearch/getShippingFee?params=%s", encodedParams) // request := gorequest.New() // if proxy != "" { // request.Proxy(proxy) // } // // 发送请求 // resp, body, errs := request.Get(url). // 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"). // End() // // 错误处理 // if len(errs) > 0 { // return nil, fmt.Errorf("请求失败: %v", errs) // } // // 检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", resp.Status) // } // responseStruct := ResponseStruct{} // err = json.Unmarshal([]byte(body), &responseStruct) // if err != nil { // return nil, fmt.Errorf("解析JSON失败: %v", err) // } // var dataItem []DataItem // for i := range responseStruct.Data { // dataItem = append(dataItem, responseStruct.Data[i]) // } // return dataItem, nil //} // //// 获取商品信息通过商品详情链接 //func outGetGoodsMsgByDetailUrl(detailUrl, proxy string) (*BookInfo, error) { // response, err := fetchResponse(detailUrl, proxy) // if err != nil { // return nil, err // } // body, err := io.ReadAll(response.Body) // if err != nil { // return nil, err // } // // 解析HTML文档 // document, err := goquery.NewDocumentFromReader(strings.NewReader(string(body))) // if err != nil { // return nil, err // } // // 获取商品信息的快递费 // fee, err := getBookDetailShippingFee(detailUrl, proxy) // if err != nil { // return nil, err // } // book := BookInfo{} // //书名 // book.BookName = strings.TrimSpace(document.Find("h1.title").Text()) // //作者等信息 // topDiv := document.Find("div.keywords-define.keywords-define-1000.clear-fix") // if topDiv.Length() > 0 { // topDiv.Find("li").Each(func(i int, li *goquery.Selection) { // titleSpan := li.Find("span.keywords-define-title") // contentSpan := li.Find("span.keywords-define-txt") // if contentSpan.Length() == 0 { // fmt.Printf("未找到指定的contentSpan信息") // } // titleText := strings.TrimSpace(titleSpan.Text()) // contentText := strings.TrimSpace(contentSpan.Text()) // titleText = strings.TrimSpace(titleText) // if strings.Contains(titleText, "作者") { // book.Author = cleanString(contentText) // } // if strings.Contains(titleText, "出版社") { // book.Publisher = contentText // } // if strings.Contains(titleText, "出版人") { // book.Publisher = contentText // } // if strings.Contains(titleText, "ISBN") { // book.ISBN = contentText // } // if strings.Contains(titleText, "出版时间") { // book.PublicationTime = validateDateFormat(contentText) // } // if strings.Contains(titleText, "版次") { // book.Edition = contentText // } // if strings.Contains(titleText, "装帧") { // book.BindingLayout = contentText // } // if strings.Contains(titleText, "开本") { // book.Format = contentText // } // if strings.Contains(titleText, "页数") { // book.Pages = contentText // } // if strings.Contains(titleText, "字数") { // book.Wordage = contentText // } // if strings.Contains(titleText, "纸张") { // book.Paper = contentText // } // if strings.Contains(titleText, "年代") { // book.Era = contentText // } // if strings.Contains(titleText, "刻印方式") { // book.EngravingMethod = contentText // } // if strings.Contains(titleText, "尺寸") { // book.Dimensions = contentText // } // if strings.Contains(titleText, "册数") { // book.VolumeNumber = contentText // } // }) // } else { // botDiv := document.Find("div.detail-lists.clear-fix") // botDiv.Find("li").Each(func(i int, li *goquery.Selection) { // spanText := strings.TrimSpace(li.Find("span").Text()) // spanText = strings.TrimSpace(spanText) // if strings.Contains(li.Text(), "作者") { // book.Author = cleanString(li.Text()) // book.Author = strings.ReplaceAll(book.Author, "作者:", "") // book.Author = strings.ReplaceAll(book.Author, "著", "") // } // if strings.Contains(li.Text(), "出版社") { // book.Publisher = spanText // } // if strings.Contains(li.Text(), "出版时间") { // book.PublicationTime = validateDateFormat(spanText) // } // if strings.Contains(li.Text(), "ISBN") { // book.ISBN = spanText // } // if strings.Contains(li.Text(), "装帧") { // book.BindingLayout = spanText // } // if strings.Contains(li.Text(), "开本") { // book.Format = spanText // } // if strings.Contains(li.Text(), "纸张") { // book.Paper = spanText // } // if strings.Contains(li.Text(), "版次") { // book.Edition = spanText // } // if strings.Contains(li.Text(), "页数") { // book.Pages = spanText // } // if strings.Contains(li.Text(), "字数") { // book.Wordage = spanText // } // }) // } // // //图片 // var imgUrls []string // tpUl := document.Find("ul.lg-list") // tpUl.Find("img").Each(func(i int, s *goquery.Selection) { // dataImgUrl, exists := s.Attr("data-imgurl") // if exists && dataImgUrl != "" { // imgUrls = append(imgUrls, dataImgUrl) // } // }) // book.BookPicS = strings.Join(imgUrls, ",") // // 售价 // price := document.Find("i.now-price-text").Text() // priceN := regexp.MustCompile(`(\d+\.?\d*)`) // if match := priceN.FindStringSubmatch(price); len(match) > 0 { // book.SellingPrice = match[1] // } // // 定价价 // fixPrice := document.Find("span.origin-price-text.clearfix").Text() // fixPriceN := regexp.MustCompile(`(\d+\.?\d*)`) // if match := fixPriceN.FindStringSubmatch(fixPrice); len(match) > 0 { // book.FixPrice = match[1] // } // // 品相 // text := document.Find("span.quality-text-cot.clearfix i").Text() // book.Condition = strings.TrimSpace(text) // // 快递费 // book.ExpressDeliveryFee = fee // return &book, nil //} // //// 获取商品信息的快递费(定位到河南) //func getBookDetailShippingFee(url, proxy string) (string, error) { // compile := regexp.MustCompile(`kongfz\.com/(\d+)/(\d+)`) // match := compile.FindStringSubmatch(url) // var shippingFee string // var shopId int // var itemId int // if len(match) == 3 { // firstNum, err := strconv.Atoi(match[1]) // 店铺ID // if err != nil { // return "", fmt.Errorf("无效的店铺编码: %s", match[1]) // } // shopId = firstNum // secondNum, err := strconv.Atoi(match[2]) // 图书ID // if err != nil { // return "", fmt.Errorf("无效的图书编码: %s", match[2]) // } // itemId = secondNum // } // shippingFeeUrl := fmt.Sprintf("https://book.kongfz.com/store-web/pc/v1/mould/calculateFee?area=13003000000&itemId=%d&shopId=%d", itemId, shopId) // // 创建HTTP客户端 // request := gorequest.New() // // 设置代理(如果有提供代理URL) // if proxy != "" { // request.Proxy(proxy) // } // // 设置超时和其他配置 // request.Timeout(30 * time.Second) // // 发送请求 // resp, body, errs := request.Get(shippingFeeUrl). // 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"). // End() // // 错误处理 // if len(errs) > 0 { // return "", fmt.Errorf("请求失败: %v", errs) // } // // 检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return "", fmt.Errorf("HTTP错误: %s", resp.Status) // } // calculateFee := struct { // ErrCode int `json:"errCode"` // ErrMessage string `json:"errMessage"` // Result struct { // FeeList []struct { // FreeCondition string `json:"freeCondition"` // ShippingID string `json:"shippingId"` // ShippingName string `json:"shippingName"` // ShippingValue string `json:"shippingValue"` // } `json:"feeList"` // FeeText string `json:"feeText"` // } `json:"result"` // Status bool `json:"status"` // }{} // // err := json.Unmarshal([]byte(body), &calculateFee) // if err != nil { // return "", fmt.Errorf("解析JSON失败: %v", err) // } // for _, fee := range calculateFee.Result.FeeList { // shippingFee = fee.ShippingValue // } // return shippingFee, nil //} // //// 公用发送请求方法 //func fetchResponse(url, proxy string) (*http.Response, error) { // log.Printf("调用的URL: %s", url) // maxRetries := cf.App.MaxRetryTimes // var detailsResp *http.Response // var errors []error // for attempt := 0; attempt < maxRetries; attempt++ { // if attempt > 0 { // log.Printf("第 %d 次重试请求...", attempt) // // 重试前等待,使用指数退避策略 // waitTime := time.Duration(attempt*attempt) * cf.App.RateLimitDelay // 平方退避 // log.Printf("等待 %v 后重试", waitTime) // time.Sleep(waitTime) // } // if proxy != "" { // detailsResp, _, errors = gorequest.New(). // Get(url). // Proxy(proxy). // Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"). // Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"). // Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"). // Timeout(120 * time.Second). // End() // } // if proxy == "" { // detailsResp, _, errors = gorequest.New(). // Get(url). // Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"). // Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"). // Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"). // Timeout(120 * time.Second). // End() // } // // 检查是否需要重试 // shouldRetry := false // if len(errors) > 0 { // shouldRetry = true // log.Printf("请求失败 (尝试 %d/%d): %v", attempt+1, maxRetries+1, errors) // } else if detailsResp == nil { // shouldRetry = true // log.Printf("响应为空 (尝试 %d/%d)", attempt+1, maxRetries+1) // } else if detailsResp.StatusCode != http.StatusOK { // // 只对服务器错误进行重试,不对客户端错误重试 // if detailsResp.StatusCode >= 500 { // shouldRetry = true // } // log.Printf("HTTP状态码: %d,HTTP请求失败: %s (尝试 %d/%d)", detailsResp.StatusCode, detailsResp.Body, attempt+1, maxRetries+1) // } // // 如果不需要重试,跳出循环 // if !shouldRetry { // break // } // // 如果是最后一次尝试,不继续重试 // if attempt == maxRetries { // break // } // // 关闭响应体(如果存在) // if detailsResp != nil && detailsResp.Body != nil { // detailsResp.Body.Close() // } // } // // 检测请求是否错误 // if len(errors) > 0 { // var proxyAuthFailed bool // var timeoutError bool // var connectionError bool // for _, e := range errors { // errStr := e.Error() // if strings.Contains(errStr, "Proxy Authentication Required") { // proxyAuthFailed = true // } // if strings.Contains(errStr, "timeout") || strings.Contains(errStr, "i/o timeout") { // timeoutError = true // } // if strings.Contains(errStr, "connection") || strings.Contains(errStr, "connect") { // connectionError = true // } // } // if proxyAuthFailed { // return nil, fmt.Errorf("代理认证失败") // } // if timeoutError { // return nil, fmt.Errorf("请求超时,经过 %d 次尝试,超时网址:%s", maxRetries+1, url) // } // if connectionError { // return nil, fmt.Errorf("网络连接错误,经过 %d 次尝试,错误网址:%s", maxRetries+1, url) // } // return nil, fmt.Errorf("查询请求失败,经过 %d 次尝试: %v,失败网址:%s", maxRetries+1, errors, url) // } // if detailsResp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", detailsResp.Status) // } // return detailsResp, nil //} // //// 获取销量榜商品列表(带有Out的都非官放标准接口) //func outGetTopGoodsListMsg(catId int, proxy string) ([]string, error) { // // 构建请求URL // url := fmt.Sprintf("https://item.kongfz.com/api/pc/getSellWellListDetail?page=1&pageSize=100&timeRank=2&catId=%d", catId) // // 创建HTTP客户端 // request := gorequest.New() // // 设置代理(如果有提供代理URL) // if proxy != "" { // request.Proxy(proxy) // } // // 设置超时和其他配置 // request.Timeout(30 * time.Second) // // 发送请求 // resp, body, errs := request.Get(url). // 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/"). // End() // // 错误处理 // if len(errs) > 0 { // return nil, fmt.Errorf("请求失败: %v", errs) // } // // 检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", resp.Status) // } // var bookDetailResponse BookDetailResponse // err := json.Unmarshal([]byte(body), &bookDetailResponse) // if err != nil { // return nil, fmt.Errorf("解析JSON失败: %v", err) // } // if !bookDetailResponse.Status { // return nil, fmt.Errorf("API返回错误: %s (代码: %d)", bookDetailResponse.ErrMessage, bookDetailResponse.ErrCode) // } // // var isbnList []string // for _, item := range bookDetailResponse.Result.Data { // if item.Isbn != "" { // isbnList = append(isbnList, item.Isbn) // } // } // isbnList = removeDuplicateISBNs(isbnList) // return isbnList, nil //} // //// 去除重复的ISBN //func removeDuplicateISBNs(isbns []string) []string { // seen := make(map[string]bool) // var result []string // for _, isbn := range isbns { // if !seen[isbn] { // seen[isbn] = true // result = append(result, isbn) // } // } // return result //} // //// 获取Document文档(带重试机制) //func fetchDocument(fetchMode, proxyType, username, password, machineCode, url string) (*goquery.Document, error) { // log.Printf("调用的URL: %s", url) // maxRetries := cf.App.MaxRetryTimes // var detailsResp *http.Response // var errors []error // var detailsBody []byte // for attempt := 0; attempt < maxRetries; attempt++ { // if attempt > 0 { // log.Printf("第 %d 次重试请求...", attempt) // // 重试前等待,使用指数退避策略 // waitTime := time.Duration(attempt*attempt) * cf.App.RateLimitDelay // 平方退避 // log.Printf("等待 %v 后重试", waitTime) // time.Sleep(waitTime) // } // if fetchMode == NotProxy { // detailsResp, _, errors = gorequest.New(). // Get(url). // Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"). // Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"). // Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"). // Timeout(120 * time.Second). // End() // } else if fetchMode == UseProxy { // detailsReq := XxProxyRequest(proxyType, username, password, machineCode). // Get(url). // Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"). // Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"). // Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8"). // Set("Connection", "close") // 每次请求关闭连接 // detailsResp, _, errors = detailsReq.End() // } else { // errors = append(errors, fmt.Errorf("请求失败,选择模式错误!")) // } // // 检查是否需要重试 // shouldRetry := false // if len(errors) > 0 { // shouldRetry = true // log.Printf("请求失败 (尝试 %d/%d): %v", attempt+1, maxRetries+1, errors) // } else if detailsResp == nil { // shouldRetry = true // log.Printf("响应为空 (尝试 %d/%d)", attempt+1, maxRetries+1) // } else if detailsResp.StatusCode != http.StatusOK { // // 只对服务器错误进行重试,不对客户端错误重试 // if detailsResp.StatusCode >= 500 { // shouldRetry = true // } // log.Printf("HTTP状态码: %d,HTTP请求失败: %s (尝试 %d/%d)", detailsResp.StatusCode, detailsResp.Body, attempt+1, maxRetries+1) // } // // 如果不需要重试,跳出循环 // if !shouldRetry { // break // } // // 如果是最后一次尝试,不继续重试 // if attempt == maxRetries { // break // } // // 关闭响应体(如果存在) // if detailsResp != nil && detailsResp.Body != nil { // detailsResp.Body.Close() // } // } // // 检测请求是否错误 // if len(errors) > 0 { // var proxyAuthFailed bool // var timeoutError bool // var connectionError bool // for _, e := range errors { // errStr := e.Error() // if strings.Contains(errStr, "Proxy Authentication Required") { // proxyAuthFailed = true // } // if strings.Contains(errStr, "timeout") || strings.Contains(errStr, "i/o timeout") { // timeoutError = true // } // if strings.Contains(errStr, "connection") || strings.Contains(errStr, "connect") { // connectionError = true // } // } // if proxyAuthFailed { // return nil, fmt.Errorf("代理认证失败") // } // if timeoutError { // return nil, fmt.Errorf("请求超时,经过 %d 次尝试,超时网址:%s", maxRetries+1, url) // } // if connectionError { // return nil, fmt.Errorf("网络连接错误,经过 %d 次尝试,错误网址:%s", maxRetries+1, url) // } // return nil, fmt.Errorf("查询请求失败,经过 %d 次尝试: %v,失败网址:%s", maxRetries+1, errors, url) // } // if detailsResp.StatusCode != http.StatusOK { // return nil, fmt.Errorf("HTTP错误: %s", detailsResp.Status) // } // // detailsBody, err := io.ReadAll(detailsResp.Body) // if err != nil { // return nil, err // } // // return goquery.NewDocumentFromReader(strings.NewReader(string(detailsBody))) //} // //// 合并基本信息和详情 //func mergeBookDetails(bookItems []BookItem, detailResults map[string]*DetailResult) []BookInfo { // var books []BookInfo // // for _, item := range bookItems { // book := item.Book // // // 如果有详情且获取成功,补充详细信息 // if item.HasDetail && item.DetailURL != "" { // if result, exists := detailResults[item.DetailURL]; exists && result.Error == nil && result.Doc != nil { // detailsDiv := result.Doc.Find("div.detail-lists.clear-fix") // if detailsDiv.Length() > 0 { // selection := detailsDiv.Find("li") // book.Author = extractNormalDetails(selection, "作者") // book.Publisher = extractNormalDetails(selection, "出版社") // detailsTime := extractNormalDetails(selection, "出版时间") // if detailsTime != "" { // formats := []string{"2006-01", "2006-01-02", "2006"} // for _, format := range formats { // if t, err := time.Parse(format, detailsTime); err == nil { // book.PublicationTime = t.Unix() // break // } // } // } // book.ISBN = extractNormalDetails(selection, "ISBN") // book.Edition = extractNormalDetails(selection, "版次") // book.FixPrice = extractNormalDetails(selection, "定价") // book.BindingLayout = extractNormalDetails(selection, "装帧") // book.Format = extractNormalDetails(selection, "开本") // book.Pages = extractNormalDetails(selection, "页数") // book.Wordage = extractNormalDetails(selection, "字数") // } // } // } // // books = append(books, book) // } // return books //} // //// 根据url获取单个图书详情信息 //func getUrlBookDetails(fetchMode, proxyType, username, password, machineCode, url string) (books []BookInfo, err error) { // document, err := fetchDocument(fetchMode, proxyType, username, password, machineCode, url) // if err != nil { // return nil, err // } // // fee, err := FetchBookDetailsShippingFee(url) // if err != nil { // return nil, err // } // book := BookInfo{} // //书名 // book.BookName = strings.TrimSpace(document.Find("h1.title").Text()) // // //作者等信息 // topDiv := document.Find("div.keywords-define.keywords-define-1000.clear-fix") // if topDiv.Length() > 0 { // topDiv.Find("li").Each(func(i int, li *goquery.Selection) { // titleSpan := li.Find("span.keywords-define-title") // contentSpan := li.Find("span.keywords-define-txt") // if contentSpan.Length() == 0 { // fmt.Printf("未找到指定的contentSpan信息") // } // titleText := strings.TrimSpace(titleSpan.Text()) // contentText := strings.TrimSpace(contentSpan.Text()) // titleText = strings.TrimSpace(titleText) // if strings.Contains(titleText, "作者") { // book.Author = cleanString(contentText) // } // if strings.Contains(titleText, "出版社") { // book.Publisher = contentText // } // if strings.Contains(titleText, "出版人") { // book.Publisher = contentText // } // if strings.Contains(titleText, "ISBN") { // book.ISBN = contentText // } // if strings.Contains(titleText, "出版时间") { // book.PublicationTime = validateDateFormat(contentText) // } // if strings.Contains(titleText, "版次") { // book.Edition = contentText // } // if strings.Contains(titleText, "装帧") { // book.BindingLayout = contentText // } // if strings.Contains(titleText, "开本") { // book.Format = contentText // } // if strings.Contains(titleText, "页数") { // book.Pages = contentText // } // if strings.Contains(titleText, "字数") { // book.Wordage = contentText // } // if strings.Contains(titleText, "纸张") { // book.Paper = contentText // } // if strings.Contains(titleText, "年代") { // book.Era = contentText // } // if strings.Contains(titleText, "刻印方式") { // book.EngravingMethod = contentText // } // if strings.Contains(titleText, "尺寸") { // book.Dimensions = contentText // } // if strings.Contains(titleText, "册数") { // book.VolumeNumber = contentText // } // }) // } else { // botDiv := document.Find("div.detail-lists.clear-fix") // botDiv.Find("li").Each(func(i int, li *goquery.Selection) { // spanText := strings.TrimSpace(li.Find("span").Text()) // spanText = strings.TrimSpace(spanText) // if strings.Contains(li.Text(), "作者") { // book.Author = cleanString(li.Text()) // book.Author = strings.ReplaceAll(book.Author, "作者:", "") // book.Author = strings.ReplaceAll(book.Author, "著", "") // } // if strings.Contains(li.Text(), "出版社") { // book.Publisher = spanText // } // if strings.Contains(li.Text(), "出版时间") { // book.PublicationTime = validateDateFormat(spanText) // } // if strings.Contains(li.Text(), "ISBN") { // book.ISBN = spanText // } // if strings.Contains(li.Text(), "装帧") { // book.BindingLayout = spanText // } // if strings.Contains(li.Text(), "开本") { // book.Format = spanText // } // if strings.Contains(li.Text(), "纸张") { // book.Paper = spanText // } // if strings.Contains(li.Text(), "版次") { // book.Edition = spanText // } // if strings.Contains(li.Text(), "页数") { // book.Pages = spanText // } // if strings.Contains(li.Text(), "字数") { // book.Wordage = spanText // } // }) // } // // //图片 // var imgUrls []string // tpUl := document.Find("ul.lg-list") // tpUl.Find("img").Each(func(i int, s *goquery.Selection) { // dataImgUrl, exists := s.Attr("data-imgurl") // if exists && dataImgUrl != "" { // imgUrls = append(imgUrls, dataImgUrl) // } // }) // book.BookPicS = strings.Join(imgUrls, ",") // // 售价 // price := document.Find("i.now-price-text").Text() // priceN := regexp.MustCompile(`(\d+\.?\d*)`) // if match := priceN.FindStringSubmatch(price); len(match) > 0 { // book.SellingPrice = match[1] // } // // 定价价 // fixPrice := document.Find("span.origin-price-text.clearfix").Text() // fixPriceN := regexp.MustCompile(`(\d+\.?\d*)`) // if match := fixPriceN.FindStringSubmatch(fixPrice); len(match) > 0 { // book.FixPrice = match[1] // } // // 品相 // text := document.Find("span.quality-text-cot.clearfix i").Text() // book.Condition = strings.TrimSpace(text) // // 快递费 // if fee != "" { // if fee == "包邮" { // book.ExpressDeliveryFee = "0" // } else { // book.ExpressDeliveryFee = fee // } // } // books = append(books, book) // return books, nil //} // //// 获取店铺页面的所有快递费用 //func FetchProductInfoWithChromedp(url string) (*ProductResponse, error) { // // 创建上下文 // opts := append(chromedp.DefaultExecAllocatorOptions[:], // chromedp.Flag("headless", true), // chromedp.Flag("disable-gpu", true), // chromedp.Flag("no-sandbox", true), // chromedp.Flag("disable-dev-shm-usage", true), // chromedp.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"), // // 禁用图片加载,加快速度 // chromedp.Flag("blink-settings", "imagesEnabled=false"), // ) // // 启动浏览器 // allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...) // defer cancel() // // 创建浏览器上下文 // ctx, cancel := chromedp.NewContext(allocCtx) // defer cancel() // // 设置超时 // ctx, cancel = context.WithTimeout(ctx, 60*time.Second) // defer cancel() // log.Printf("[CHROMEDP] 开始导航到URL: %s", url) // // 第一步:先导航到页面并等待完全加载 // err := chromedp.Run(ctx, // // 导航到目标页面 // chromedp.Navigate(url), // // // 等待页面初步加载 // chromedp.WaitReady("body", chromedp.ByQuery), // chromedp.Sleep(3*time.Second), // // // 第二步:刷新页面,重新加载动态内容 // chromedp.Reload(), // // // 等待刷新后页面加载 // chromedp.WaitReady("body", chromedp.ByQuery), // chromedp.Sleep(5*time.Second), // // // 等待关键元素出现 // chromedp.WaitVisible(".item.clearfix", chromedp.ByQuery), // // // 滚动页面以触发动态加载 // chromedp.Evaluate(`window.scrollTo(0, document.body.scrollHeight / 3)`, nil), // chromedp.Sleep(2*time.Second), // chromedp.Evaluate(`window.scrollTo(0, document.body.scrollHeight / 2)`, nil), // chromedp.Sleep(2*time.Second), // chromedp.Evaluate(`window.scrollTo(0, document.body.scrollHeight)`, nil), // chromedp.Sleep(3*time.Second), // chromedp.Evaluate(`window.scrollTo(0, 0)`, nil), // chromedp.Sleep(1*time.Second), // ) // if err != nil { // log.Printf("[CHROMEDP] 页面导航失败: %v", err) // return nil, fmt.Errorf("页面导航失败: %v", err) // } // log.Printf("[CHROMEDP] 页面导航完成,开始提取数据") // var evalResult map[string]interface{} // // 执行任务 // err = chromedp.Run(ctx, // // 导航到目标页面 // chromedp.Navigate(url), // // // 执行 JavaScript 来提取商品信息 // chromedp.Evaluate(`(function() { // console.log("开始提取商品信息..."); // try { // let productData = []; // // 查找所有商品项 - 针对孔夫子旧书网的特定选择器 // const itemSelectors = [ // '.item.clearfix', // '.list-item', // '.product-item', // '.goods-item', // '[class*="item"]' // ]; // let items = []; // for (let selector of itemSelectors) { // const found = document.querySelectorAll(selector); // if (found.length > 0) { // items = found; // console.log("使用选择器:", selector, "找到项目数:", items.length); // break; // } // } // // if (items.length === 0) { // // 如果没有找到特定选择器,尝试查找任何看起来像商品的项目 // items = document.querySelectorAll('div[class*="item"], li[class*="item"]'); // console.log("使用通用选择器找到项目数:", items.length); // } // console.log("总共找到商品项:", items.length); // // 遍历每个商品项 // items.forEach((item, index) => { // // 提取 itemid // let itemId = ''; // // // 方法1: 从元素属性获取 // if (item.hasAttribute('itemid')) { // itemId = item.getAttribute('itemid'); // } // // // 方法2: 从数据属性获取 // if (!itemId && item.hasAttribute('data-itemid')) { // itemId = item.getAttribute('data-itemid'); // } // // // 方法3: 从ID属性获取 // if (!itemId && item.hasAttribute('id')) { // const id = item.getAttribute('id'); // if (id.includes('item') || id.includes('product')) { // itemId = id; // } // } // // // 方法4: 从链接中提取itemid // if (!itemId) { // const links = item.querySelectorAll('a[href*="item"], a[href*="product"]'); // for (let link of links) { // const href = link.getAttribute('href'); // if (href) { // const itemMatch = href.match(/(?:item|product)[_-]?(\d+)/i); // if (itemMatch) { // itemId = itemMatch[1]; // break; // } // } // } // } // // // 方法5: 从子元素中查找itemid // if (!itemId) { // const childWithItemId = item.querySelector('[itemid], [data-itemid]'); // if (childWithItemId) { // if (childWithItemId.hasAttribute('itemid')) { // itemId = childWithItemId.getAttribute('itemid'); // } else if (childWithItemId.hasAttribute('data-itemid')) { // itemId = childWithItemId.getAttribute('data-itemid'); // } // } // } // // // 提取书名 // let bookName = ''; // const titleSelectors = [ // '.title a', // '.book-title', // '.item-title', // '.name a', // 'h3 a', // 'h4 a', // '.link', // 'a[title]' // ]; // // for (let selector of titleSelectors) { // const titleEl = item.querySelector(selector); // if (titleEl) { // bookName = titleEl.textContent.trim(); // if (bookName && bookName.length > 1) { // break; // } // } // } // // // 如果没找到,尝试在item内查找任何文本作为书名 // if (!bookName) { // const textContent = item.textContent; // // 尝试提取看起来像书名的文本(较长的文本块) // const lines = textContent.split('\n').map(line => line.trim()).filter(line => line.length > 5); // if (lines.length > 0) { // bookName = lines[0]; // } // } // // // 提取价格 // let price = ''; // const priceSelectors = [ // '.price span', // '.price .bold', // '.current-price', // '.sell-price', // '.cost', // '.money', // '[class*="price"]', // 'strong' // ]; // // for (let selector of priceSelectors) { // const priceEl = item.querySelector(selector); // if (priceEl) { // let priceText = priceEl.textContent.trim(); // // 清理价格文本,保留数字和小数点 // priceText = priceText.replace(/[^\d\.]/g, ''); // if (priceText && !isNaN(parseFloat(priceText))) { // price = '¥' + priceText; // break; // } // } // } // // // 如果没找到价格,尝试在文本中查找价格模式 // if (!price) { // const itemText = item.textContent; // const priceMatch = itemText.match(/[¥¥]?\s*(\d+\.?\d*)/); // if (priceMatch) { // price = '¥' + priceMatch[1]; // } // } // // // 提取快递费用 // let shippingFee = ''; // const shippingSelectors = [ // '.ship-fee', // '.shipping-fee', // '.express-fee', // '.freight', // '.postage', // '[class*="fee"]', // '[class*="快递"]', // '[class*="运费"]' // ]; // // for (let selector of shippingSelectors) { // const shippingEl = item.querySelector(selector); // if (shippingEl) { // shippingFee = shippingEl.textContent.trim(); // if (shippingFee) break; // } // } // // // 如果没找到运费元素,尝试在文本中查找运费关键词 // if (!shippingFee) { // const itemText = item.textContent; // const feeMatches = itemText.match(/(运费[::]\s*[^\s\n]+)|(快递[::]\s*[^\s\n]+)|(邮费[::]\s*[^\s\n]+)/); // if (feeMatches) { // shippingFee = feeMatches[0]; // } else if (itemText.includes('包邮') || itemText.includes('免运费')) { // shippingFee = '包邮'; // } else { // shippingFee = '运费待确认'; // } // } // // // 清理书名(移除过长的文本) // if (bookName && bookName.length > 100) { // bookName = bookName.substring(0, 100) + '...'; // } // // // 如果还没有itemid,生成一个基于索引的ID // if (!itemId) { // itemId = 'item_' + (index + 1); // } // // // 添加到数据中 // productData.push({ // itemId: itemId, // bookName: bookName || '商品${index + 1}', // price: price || '价格待确认', // shippingFee: shippingFee // }); // }); // // // 过滤掉明显无效的数据 // productData = productData.filter(item => // (item.bookName !== '商品1' || item.price !== '价格待确认') && // item.bookName && item.bookName.length > 0 // ); // // console.log("处理后商品数量:", productData.length); // if (productData.length > 0) { // console.log("前3个商品示例:", productData.slice(0, 3)); // } // // return { // success: true, // message: "成功提取商品信息", // data: productData // }; // // } catch(error) { // console.error("提取商品信息时出错:", error); // return { // success: false, // message: "提取商品信息时出错: " + error.message, // data: [] // }; // } // })()`, &evalResult), // ) // // if err != nil { // return nil, fmt.Errorf("chromedp执行失败: %v", err) // } // // // 处理 JavaScript 执行结果 // response := &ProductResponse{} // // // 转换结果数据 // if success, ok := evalResult["success"].(bool); ok { // response.Success = success // } // if message, ok := evalResult["message"].(string); ok { // response.Message = message // } // if data, ok := evalResult["data"].([]interface{}); ok { // for _, item := range data { // if productMap, ok := item.(map[string]interface{}); ok { // product := ProductInfo{} // if itemId, ok := productMap["itemId"].(string); ok { // product.ItemID = itemId // } // if bookName, ok := productMap["bookName"].(string); ok { // product.BookName = bookName // } // if price, ok := productMap["price"].(string); ok { // product.Price = price // } // if shippingFee, ok := productMap["shippingFee"].(string); ok { // info := extractShippingInfo(shippingFee) // product.ShippingFee = info // } // response.Data = append(response.Data, product) // } // } // } // // return response, nil //} // //// 获取详情页的快递费用 //func FetchBookDetailsShippingFee(url string) (string, error) { // // 创建上下文 // opts := append(chromedp.DefaultExecAllocatorOptions[:], // chromedp.Flag("headless", true), // chromedp.Flag("disable-gpu", true), // chromedp.Flag("no-sandbox", true), // chromedp.Flag("disable-dev-shm-usage", true), // chromedp.UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"), // // 禁用图片加载,加快速度 // chromedp.Flag("blink-settings", "imagesEnabled=false"), // ) // // 启动浏览器 // allocCtx, cancel := chromedp.NewExecAllocator(context.Background(), opts...) // defer cancel() // // 创建浏览器上下文 // ctx, cancel := chromedp.NewContext(allocCtx) // defer cancel() // // 设置超时 // ctx, cancel = context.WithTimeout(ctx, 60*time.Second) // defer cancel() // log.Printf("[CHROMEDP] 开始导航到URL: %s", url) // var result string // // // 增强的 JavaScript 脚本 // enhancedJSScript := ` // (function() { // // 查找包含快递费用的元素 // const elements = document.querySelectorAll('*'); // let shippingFee = null; // // elements.forEach(element => { // if (element.textContent.includes('快递¥')) { // const match = element.textContent.match(/快递¥(\d+\.\d{2})/); // if (match) { // shippingFee = match[1]; // console.log('找到快递费用: ¥' + shippingFee); // } // } // // 匹配格式2: 快递:包邮 // else if (element.textContent.includes('快递:包邮') || element.textContent.includes('快递:包邮')) { // shippingFee = '包邮'; // console.log('找到快递费用: 包邮'); // } // // 匹配格式3: 快递 包邮 (包含空格变体) // else if (element.textContent.match(/快递[::\s]包邮/)) { // shippingFee = '包邮'; // console.log('找到快递费用: 包邮'); // } // }); // // if (!shippingFee) { // // 如果没找到,尝试搜索整个页面 // const pageText = document.body.innerText; // const match = pageText.match(/快递¥(\d+\.\d{2})/); // if (match) { // shippingFee = match[1]; // console.log('找到快递费用: ¥' + shippingFee); // } // // 尝试匹配包邮 // else if (pageText.match(/快递[::\s]包邮/)) { // shippingFee = '包邮'; // console.log('找到快递费用: 包邮'); // } // // 尝试其他包邮表述 // else if (pageText.includes('包邮') && pageText.includes('快递')) { // shippingFee = '包邮'; // console.log('找到快递费用: 包邮'); // } // else { // console.log('未找到快递费用信息'); // } // } // return shippingFee; // })();` // // 先导航到页面并等待完全加载 // err := chromedp.Run(ctx, // // 导航到目标页面 // chromedp.Navigate(url), // // 刷新页面,重新加载动态内容 // chromedp.Reload(), // // 等待刷新后页面加载 // chromedp.WaitReady("body", chromedp.ByQuery), // chromedp.Sleep(8*time.Second), // // 执行 JavaScript 来提取商品信息 // chromedp.Evaluate(enhancedJSScript, &result), // ) // if err != nil { // log.Printf("[CHROMEDP] 页面导航失败: %v", err) // return "", fmt.Errorf("页面导航失败: %v", err) // } // log.Printf("[CHROMEDP] 页面导航完成,开始提取数据") // // if err != nil { // return "", fmt.Errorf("chromedp执行失败: %v", err) // } // return result, nil //} // //// 获取孔网实拍图(查询商品列表) //func getKFZSPTImageURL(proxyType, username, password, machineCode, isbn string) (*BookInfo, error) { // log.Printf("[DEBUG] ", isbn, " 获取图书ISBN: %s", isbn) // url := fmt.Sprintf("%s?dataType=0&keyword=%s&page=1&size=%d&sortType=7&actionPath=quality,sortType&quality=85~&quaSelect=2&userArea=13003000000", cf.API.ProductSearchURL, isbn, cf.App.Size) // // req := XxProxyRequest(proxyType, username, password, machineCode). // Get(url). // Set("User-Agent", cf.App.DefaultUserAgent). // Set("Accept", "*/*") // resp, body, errs := req.End() // log.Printf("[DEBUG] 获取图书列表 URL: %s", url) // // // 只在有响应内容时才打印,避免日志过长 // if len(body) > 0 && len(body) < 500 { // log.Printf("[DEBUG] 获取图书列表响应: %s", body) // } else if len(body) > 0 { // log.Printf("[DEBUG] 获取图书列表响应长度: %d 字符", len(body)) // } else { // log.Printf("[DEBUG] 获取图书列表响应为空") // } // // // 处理请求错误 // if len(errs) > 0 { // // 检查是否是代理认证失败 // var proxyAuthFailed bool // for _, e := range errs { // if strings.Contains(e.Error(), "Proxy Authentication Required") { // proxyAuthFailed = true // break // } // } // if proxyAuthFailed { // return nil, fmt.Errorf("代理认证失败") // } // return nil, fmt.Errorf("查询请求失败: %v", errs) // } // // // 检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // space := strings.TrimSpace(resp.Status) // return nil, fmt.Errorf("HTTP错误: %s", space) // } // // // 解析响应 // var apiResp 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 { // Title string `json:"title"` // ImgUrl string `json:"imgUrl"` // ImgBigUrl string `json:"imgBigUrl"` // ItemId int64 `json:"itemId"` // ShopId int64 `json:"shopId"` // TplRecords []struct { // Key string `json:"key"` // Value string `json:"value"` // } `json:"tplRecords"` // } `json:"list"` // } `json:"itemResponse"` // } `json:"data"` // } // // if err := json.Unmarshal([]byte(body), &apiResp); err != nil { // return nil, fmt.Errorf("解析JSON失败: %w", err) // } // // // 如果找到商品,返回图片URL // if apiResp.Data.ItemResponse.Total > 0 && len(apiResp.Data.ItemResponse.List) > 0 { // // 确定起始索引 // var startIndex int // if cf.App.Size >= apiResp.Data.ItemResponse.Total { // startIndex = apiResp.Data.ItemResponse.Total - 1 // } else { // startIndex = cf.App.Size - 1 // } // // // 从指定索引开始,向前查找有效图片,最多重试3次 // for attempt := 0; attempt < 3; attempt++ { // currentIndex := startIndex - attempt // // // 检查索引是否有效 // if currentIndex < 0 || currentIndex >= len(apiResp.Data.ItemResponse.List) { // log.Printf("[DEBUG] 索引 %d 超出范围,跳过", currentIndex) // continue // } // // item := apiResp.Data.ItemResponse.List[currentIndex] // // // 检查图片URL是否存在 // if item.ImgBigUrl == "" { // log.Printf("[DEBUG] 索引 %d 的图片URL为空,跳过", currentIndex) // continue // } // // info := &BookInfo{} // info.BookName = item.Title // info.BookPicS = item.ImgUrl // info.ItemId = item.ItemId // info.ShopId = item.ShopId // // // 安全地获取TplRecords中的值 // if len(item.TplRecords) > 0 { // info.Author = item.TplRecords[0].Value // } // if len(item.TplRecords) > 1 { // info.Publisher = item.TplRecords[1].Value // } // if len(item.TplRecords) > 2 { // info.PublicationTime = validateDateFormat(item.TplRecords[2].Value) // } // if len(item.TplRecords) > 3 { // info.BindingLayout = item.TplRecords[3].Value // } // // // 成功时重置代理失败计数器 // resetProxyFailCount() // return info, nil // } // // 如果所有尝试都失败了,返回错误 // log.Printf("[WARN] 经过3次尝试,未找到有效图片") // return nil, fmt.Errorf("未找到有效图片,已尝试3次") // } // return nil, nil //} // //// 获取孔网官图(查询图书条目) //func getKFZGTImageURL(proxyType, username, password, machineCode, isbn string) (*BookInfo, error) { // url := fmt.Sprintf("%s?keyword=%s", cf.API.BookSearchURL, isbn) // // info := &BookInfo{} // // req := XxProxyRequest(proxyType, username, password, machineCode). // Get(url). // Set("User-Agent", cf.App.DefaultUserAgent). // Set("Accept", "*/*") // resp, body, errs := req.End() // log.Printf("[DEBUG] 获取图书条目 URL: %s", url) // // 只在有响应内容时才打印,避免日志过长 // if len(body) > 0 && len(body) < 500 { // log.Printf("[DEBUG] 获取图书条目响应: %s", body) // } else if len(body) > 0 { // log.Printf("[DEBUG] 获取图书条目响应长度: %d 字符", len(body)) // } else { // log.Printf("[DEBUG] 获取图书条目响应为空") // } // // // 处理请求错误 // if len(errs) > 0 { // // 检查是否是代理相关错误 // var isProxyError bool // var errorDetails []string // for _, e := range errs { // 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", errs) // } // // //检查HTTP状态码 // if resp.StatusCode != http.StatusOK { // space := strings.TrimSpace(resp.Status) // return nil, fmt.Errorf("HTTP错误: %s", space) // } // // // 解析响应 // var apiResp 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"` // BookShowInfo []string `json:"bookShowInfo"` // } `json:"list"` // } `json:"itemResponse"` // } `json:"data"` // } // // if err := json.Unmarshal([]byte(body), &apiResp); err != nil { // return nil, fmt.Errorf("解析JSON失败: %w", err) // } // // // 如果找到条目,返回图片URL // if apiResp.Data.ItemResponse.Total > 0 && len(apiResp.Data.ItemResponse.List) > 0 { // list := apiResp.Data.ItemResponse.List[0] // info := list.BookShowInfo // // bookItem := &BookInfo{ // BookName: list.BookName, // BookPic: list.ImgUrlEntity.BigImgUrl, // Mid: list.Mid, // } // // // 根据长度安全填充字段 // if len(info) > 0 { // bookItem.Author = info[0] // } // if len(info) > 1 { // bookItem.Publisher = info[1] // } // if len(info) > 2 { // bookItem.PublicationTime = validateDateFormat(info[2]) // } // if len(info) > 3 { // bookItem.BindingLayout = info[3] // } // if len(info) > 4 { // bookItem.FixPrice = info[4] // } else { // log.Printf("[WARN] BookShowInfo 长度不足 (仅 %d 项): %v", len(info), info) // } // // fmt.Println("bookItem: ", bookItem) // return bookItem, nil // } // // return info, nil //} // //// 替换所有空白字符为空格 //func cleanString(s string) string { // s = strings.ReplaceAll(s, "\n", "") // s = strings.ReplaceAll(s, "\r", "") // s = strings.ReplaceAll(s, "\t", "") // s = strings.ReplaceAll(s, " ", "") // return removeDuplicates(s) //} // //// 字符串去重 //func removeDuplicates(s string) string { // seen := make(map[rune]bool) // var result strings.Builder // for _, r := range s { // if !seen[r] { // seen[r] = true // result.WriteRune(r) // } // } // return result.String() //} // //// 检测快递费用格式 //func extractShippingInfo(shippingFee string) string { // // 匹配 "快递¥数字" 格式 // re1 := regexp.MustCompile(`快递¥(\d+\.?\d*)`) // // 匹配 "包邮" 格式 // re2 := regexp.MustCompile(`(包邮)`) // // if matches := re1.FindStringSubmatch(shippingFee); len(matches) > 1 { // return matches[1] // 返回数字部分 // } // // if matches := re2.FindStringSubmatch(shippingFee); len(matches) > 1 { // return "0" // 返回"包邮" // } // // return "" //} // //// 改进字段 //func extractNormalDetails(s *goquery.Selection, fieldName string) string { // var info string // s.Each(func(i int, selection *goquery.Selection) { // if strings.Contains(selection.Text(), fieldName) { // all := strings.ReplaceAll(selection.Text(), " ", "") // all = strings.ReplaceAll(all, "\n", "") // all = strings.ReplaceAll(all, " ", "") // split := strings.SplitN(all, ":", 2) // if len(split) > 1 { // info = split[1] // } else { // return // } // } // }) // return info //} // //// 改进的字段提取函数 //func extractNormalText(s *goquery.Selection, fieldName string) string { // // 在左右两个分区中查找 // selectors := []string{"div.f_left", "div.f_right"} // for _, selector := range selectors { // fieldItem := s.Find(selector + " div.normal-item").FilterFunction(func(i int, sel *goquery.Selection) bool { // title := sel.Find("span.normal-title").Text() // return strings.Contains(title, fieldName) // }) // // if fieldItem.Length() > 0 { // text := fieldItem.Find("span.normal-text").Text() // return strings.TrimSpace(text) // } // } // return "" //} // //// 重置代理失败计数器(成功时调用) //func resetProxyFailCount() { // tailProxyMu.Lock() // defer tailProxyMu.Unlock() // proxyFailCount = 0 //} // //// 验证日期格式 //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() //} // //// 代理请求(小象代理) //func XxProxyRequest(proxyType, username, password, machineCode string) *gorequest.SuperAgent { // proxyManagerOnce.Do(func() { // log.Printf("[INFO] 初始化代理管理器,DLL路径: %s", cf.Proxy.ProxyFilePath) // // // 检查DLL文件是否存在 // if _, err := os.Stat(cf.Proxy.ProxyFilePath); os.IsNotExist(err) { // // 尝试在可执行文件目录查找 // exePath, _ := os.Executable() // exeDir := filepath.Dir(exePath) // dllPath := filepath.Join(exeDir, cf.Proxy.ProxyFilePath) // // if _, err := os.Stat(dllPath); err == nil { // cf.Proxy.ProxyFilePath = dllPath // } else { // proxyManagerInitErr = fmt.Errorf("代理DLL文件不存在: %s (也尝试了: %s)", cf.Proxy.ProxyFilePath, dllPath) // return // } // } // // globalProxyManager, proxyManagerInitErr = NewProxyConfigManager(cf.Proxy.ProxyFilePath) // if proxyManagerInitErr != nil { // log.Printf("[ERROR] 代理管理器初始化失败: %v", proxyManagerInitErr) // } else { // log.Printf("[INFO] 代理管理器初始化成功") // } // }) // typeManager, err := globalProxyManager.ProxyTypeManager( // proxyType, // username, // password, // machineCode, // ) // if err != nil { // fmt.Printf("获取代理服务器信息失败: %v", err) // } // return gorequest.New().Proxy(typeManager).Timeout(120*time.Second).Retry(2, 3*time.Second) //} // //// 初始化 //func initializeConfig(config Config) { // // 设置全局配置 // cf = config //} // //// 连接数据库(选品) //func connectDBXP() (*sql.DB, error) { // db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", // cf.Database.Username, cf.Database.Password, cf.Database.Host, cf.Database.Name)) // if err != nil { // return nil, fmt.Errorf("打开数据库连接失败: %v", err) // } // // 设置连接池参数 // db.SetMaxOpenConns(20) // 最大打开连接数 // db.SetMaxIdleConns(10) // 最大空闲连接数 // err = db.Ping() // if err != nil { // return nil, fmt.Errorf("数据库连接测试失败: %v", err) // } // return db, nil //} // //// 从数据库随机获取一个可用账号 //func getRandomAccount() (*AccountCredential, error) { // mu.RLock() // defer mu.RUnlock() // // sql语句 // query := ` // SELECT id, credential_account, credential_password, token // FROM t_credential // WHERE credential_type = 'KWCredential' // AND status = 0 // AND is_del = 0 // ORDER BY RAND() // LIMIT 1` // // db, err := connectDBXP() // if err != nil { // return nil, err // } // var ac AccountCredential // err = db.QueryRow(query).Scan(&ac.ID, &ac.Username, &ac.Password, &ac.Token) // if err != nil { // if err == sql.ErrNoRows { // return nil, fmt.Errorf("没有可用的账号") // } // return nil, fmt.Errorf("查询账号失败: %v", err) // } // return &ac, nil //} // //// 修改账号为不可用 //func updateAccountInvalid(id int64) error { // mu.RLock() // defer mu.RUnlock() // db, err := connectDBXP() // if err != nil { // return err // } // query := `UPDATE t_credential SET is_del = 1 WHERE id = ?` // _, err = db.Exec(query, id) // return fmt.Errorf("更新失败: %v", err) //} // //// 修改账号为需要验证 //func updateAccountNeedVerify(id int64) error { // mu.RLock() // defer mu.RUnlock() // db, err := connectDBXP() // if err != nil { // return err // } // query := `UPDATE t_credential SET status = 1 WHERE id = ?` // _, err = db.Exec(query, id) // return err //} // //// 更新账号token //func updateAccountToken(id int64, token string) error { // mu.RLock() // defer mu.RUnlock() // db, err := connectDBXP() // if err != nil { // return err // } // query := `UPDATE t_credential SET token = ? WHERE id = ?` // _, err = db.Exec(query, token, id) // return err //} // //// 登录(带有Out的都非官方标准接口) //// ////export OutLogin //func OutLogin(username, password *C.char) *C.char { // goUsername := C.GoString(username) // goPassword := C.GoString(password) // respToken, err := outLogin(goUsername, goPassword) // resp := struct { // Token string `json:"token"` // }{ // Token: respToken, // } // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: resp, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 获取用户信息(带有Out的都非官方标准接口) //// ////export OutGetUserMsg //func OutGetUserMsg(token *C.char) *C.char { // goToken := C.GoString(token) // userInfo, err := outGetUserMsg(goToken) // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: userInfo, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 获取商品模版(带有Out的都非官方标准接口) //// ////export OutGetGoodsTplMsg //func OutGetGoodsTplMsg(token, itemId, proxy *C.char) *C.char { // goToken := C.GoString(token) // goItemId := C.GoString(itemId) // goProxy := C.GoString(proxy) // info, err := outGetGoodsTplMsg(goToken, goItemId, goProxy) // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: info, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 获取商品列表-已登的店铺(带有Out的都非官方标准接口) //// ////export OutGetGoodsListMsgFromSelfShop //func OutGetGoodsListMsgFromSelfShop(token, proxy, itemSn, priceMin, priceMax *C.char, startCreateTime C.int, // endCreateTime C.int, requestType *C.char, isItemSnEqual C.int, page C.int, size C.int) *C.char { // goToken := C.GoString(token) // goProxy := C.GoString(proxy) // goItemSn := C.GoString(itemSn) // goPriceMin := C.GoString(priceMin) // goPriceMax := C.GoString(priceMax) // goStartCreateTime := int(startCreateTime) // goEndCreateTime := int(endCreateTime) // goRequestType := C.GoString(requestType) // goIsItemSnEqual := int(isItemSnEqual) // goPage := int(page) // goSize := int(size) // info, err := outGetGoodsListMsgFromSelfShop(goToken, goProxy, goItemSn, goPriceMin, goPriceMax, goStartCreateTime, goEndCreateTime, goRequestType, goIsItemSnEqual, goPage, goSize) // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: info, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 删除商品-已登的店铺(带有Out的都非官方标准接口) //// ////export OutDelGoodsFromSelfShop //func OutDelGoodsFromSelfShop(token, proxy, itemId *C.char) *C.char { // goToken := C.GoString(token) // goProxy := C.GoString(proxy) // goItemId := C.GoString(itemId) // info, err := outDelGoodsFromSelfShop(goToken, goProxy, goItemId) // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: info, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 新增商品(带有Out的都非官方标准接口) //// ////export OutAddGoods //func OutAddGoods(token, proxy, formData *C.char) *C.char { // goToken := C.GoString(token) // goProxy := C.GoString(proxy) // goFormData := C.GoString(formData) // info, err := outAddGoods(goToken, goProxy, goFormData) // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: info, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 获取图片URL(官图和拍图)带有店铺过滤 //// ////export OutGetImageFilterShopId //func OutGetImageFilterShopId(token, isbn *C.char, shopId C.int, proxy *C.char, isLiveImage C.int, isReturnMsg C.int) *C.char { // goToken := C.GoString(token) // goIsbn := C.GoString(isbn) // goShopId := int(shopId) // goProxy := C.GoString(proxy) // goIsLiveImage := int(isLiveImage) // goIsReturnMsg := int(isReturnMsg) // info, err := outGetImageFilterShopId(goToken, goIsbn, goShopId, goProxy, goIsLiveImage, goIsReturnMsg) // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: info, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 获取商品图片(带有Out的都非官方标准接口) //// ////export OutGetImageByIsbn //func OutGetImageByIsbn(token, isbn, proxy *C.char, isLiveImage C.int, isReturnMsg C.int) *C.char { // goToken := C.GoString(token) // goIsbn := C.GoString(isbn) // goProxy := C.GoString(proxy) // goIsLiveImage := int(isLiveImage) // goIsReturnMsg := int(isReturnMsg) // bookInfo, err := outGetImageByIsbn(goToken, goIsbn, goProxy, goIsLiveImage, goIsReturnMsg) // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: bookInfo, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 获取商品列表通过店铺ID(带有Out的都非官方标准接口) //// ////export OutGetGoodsListMsgByShopId //func OutGetGoodsListMsgByShopId(shopId C.int, proxy *C.char, retPrice C.int, isImage C.int, sortType *C.char, sort *C.char, priceMin C.float, priceMax C.float, pageNum, returnNum C.int) *C.char { // goShopId := int(shopId) // goProxy := C.GoString(proxy) // goRetPrice := int(retPrice) // goIsImage := int(isImage) // goSortType := C.GoString(sortType) // goSort := C.GoString(sort) // goPriceMin := float32(priceMin) // goPriceMax := float32(priceMax) // goPageNum := int(pageNum) // goReturnNum := int(returnNum) // books, num, pNum, err := outGetGoodsListMsgByShopId(goShopId, goProxy, goRetPrice, goIsImage, goSortType, goSort, goPriceMin, goPriceMax, goPageNum, goReturnNum) // // 构建统一格式的响应 // bookInfo := struct { // GoodsNum string `json:"goods_num,omitempty"` // PNum string `json:"pnum,omitempty"` // Data interface{} `json:"data,omitempty"` // }{ // GoodsNum: num, // PNum: pNum, // Data: books, // } // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: bookInfo, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 获取商品信息通过商品详情链接(带有0ut的都非官方标准接口) //// ////export OutGetGoodsMsgByDetailUrl //func OutGetGoodsMsgByDetailUrl(detailUrl, proxy *C.char) *C.char { // goDetailUrl := C.GoString(detailUrl) // goProxy := C.GoString(proxy) // response, err := outGetGoodsMsgByDetailUrl(goDetailUrl, goProxy) // // 构建统一格式的响应 // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: response, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // //// 获取销量榜商品列表(带有Out的都非官放标准接口) //// ////export OutGetTopGoodsListMsg //func OutGetTopGoodsListMsg(catId C.int, proxy *C.char) *C.char { // goCatId := int(catId) // goProxy := C.GoString(proxy) // response, err := outGetTopGoodsListMsg(goCatId, goProxy) // // 构建统一格式的响应 // var apiResponse APIResponse // if err != nil { // apiResponse = APIResponse{ // Success: false, // Message: err.Error(), // } // } else { // apiResponse = APIResponse{ // Success: true, // Data: response, // } // } // // 转换为JSON字符串 // jsonData, marshalErr := json.Marshal(apiResponse) // if marshalErr != nil { // // 如果JSON序列化失败,返回错误信息 // apiResponse = APIResponse{ // Success: false, // Message: fmt.Sprintf("JSON序列化失败: %v", marshalErr), // } // errorJson, _ := json.Marshal(apiResponse) // return C.CString(string(errorJson)) // } // return C.CString(string(jsonData)) //} // ////export Initialize //func Initialize(configJSON *C.char) *C.char { // configStr := C.GoString(configJSON) // log.Printf("[DEBUG] 接收到的配置JSON: %s", configStr) // // var config Config // if err := json.Unmarshal([]byte(configStr), &config); err != nil { // return C.CString(fmt.Sprintf(`{"success":false,"message":"配置解析失败: %v"}`, err)) // } // initializeConfig(config) // // return C.CString(`{"success":true,"message":"初始化成功"}`) //} // //// 导出函数:释放C字符串内存 //// ////export FreeCString //func FreeCString(str *C.char) { // C.free(unsafe.Pointer(str)) //} // //// 空main函数,编译DLL时需要 //func main() { //}