package main import ( "crypto/tls" "fmt" "io" "net/http" "os" "path/filepath" "sync" "time" ) func downloadImages(images map[string]string, dir string) (map[string]bool, map[string]error) { var mu sync.Mutex var wg sync.WaitGroup success := make(map[string]bool) errors := make(map[string]error) // 并发控制:最多同时下载5张图片 semaphore := make(chan struct{}, 5) for key, url := range images { wg.Add(1) go func(key, url string) { defer wg.Done() // 获取信号量 semaphore <- struct{}{} defer func() { <-semaphore }() // 下载图片 err := downloadImage(url, dir, key) mu.Lock() if err != nil { errors[key] = err } else { success[key] = true } mu.Unlock() }(key, url) } wg.Wait() return success, errors } func downloadImage(url, dir, filename string) error { // 创建HTTP客户端 client := &http.Client{ Timeout: 30 * time.Second, Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, } // 创建请求 req, err := http.NewRequest("GET", url, nil) if err != nil { return fmt.Errorf("创建请求失败: %v", err) } // 设置请求头(模拟浏览器) req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") req.Header.Set("Accept", "image/webp,image/apng,image/*,*/*;q=0.8") req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8") req.Header.Set("Referer", "https://hd4k.com/") // 发送请求 resp, err := client.Do(req) if err != nil { return fmt.Errorf("请求失败: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return fmt.Errorf("HTTP错误: %s", resp.Status) } // 获取文件扩展名 ext := getFileExtension(url) fullFilename := filename + ext filePath := filepath.Join(dir, fullFilename) // 创建文件 file, err := os.Create(filePath) if err != nil { return fmt.Errorf("创建文件失败: %v", err) } defer file.Close() // 下载并保存 _, err = io.Copy(file, resp.Body) if err != nil { // 删除可能已损坏的文件 os.Remove(filePath) return fmt.Errorf("保存文件失败: %v", err) } return nil }