package main import ( "fmt" "github.com/gocolly/colly" "github.com/tidwall/gjson" "io" "io/ioutil" "log" "net/http" "os" "path/filepath" "time" "sync" ) var ( downloadDestFolder = "/data/Music" w sync.WaitGroup ) func main() { url := "http://www.kuwo.cn/bang/index" c := colly.NewCollector() c.OnHTML(".leftNav", func(element *colly.HTMLElement) { element.ForEach("div.classify.bang > ul > li", func(i int, e *colly.HTMLElement) { name := e.Attr("data-name") bangid := e.Attr("data-bangid") parseBangdan(name, bangid) }) }) c.Visit(url) } func parseBangdan(BangName string, bangId string) { fmt.Println("正在解析:", BangName, "……") url := fmt.Sprintf("http://www.kuwo.cn/bang/content?name=%s&bangId=%s", BangName, bangId) c := colly.NewCollector() c.OnHTML(".tools", func(element *colly.HTMLElement) { json := element.Attr("data-music") musicId := gjson.Get(json, "id") musicName := gjson.Get(json, "name") //artist := gjson.Get(json, "artist") //fmt.Println(json) client := http.Client{Timeout: 900 * time.Second} url := fmt.Sprintf("http://antiserver.kuwo.cn/anti.s?format=mp3&type=convert_url&rid=%s&response=url", musicId) resp, _ := client.Get(url) body, _ := ioutil.ReadAll(resp.Body) resp.Body.Close() w.Add(1) go downloadGedan(string(body), BangName, fmt.Sprintf("%s.mp3", musicName)) time.Sleep(time.Duration(500)*time.Millisecond) }) c.Visit(url) w.Wait() } func downloadGedan(url string, BangName string, filename string) { defer w.Done() nt := time.Now().Format("2006-01-02 15:04:05") _ = os.MkdirAll(downloadDestFolder+string(filepath.Separator)+BangName, 0777) fpath := downloadDestFolder + string(filepath.Separator) + BangName + string(filepath.Separator) + filename if PathExists(fpath) { fmt.Printf("[%s]已下载完成,跳过 %s\n", nt, filename) return } else { os.Remove(fpath + ".tmp") } fmt.Printf("[%s]正在下载 %s\n", nt, filename) newFile, err := os.Create(fpath + ".tmp") if err != nil { fmt.Println(err.Error()) } client := http.Client{Timeout: 900 * time.Second} resp, err := client.Get(url) defer resp.Body.Close() _, err = io.Copy(newFile, resp.Body) if err != nil { fmt.Println(err.Error()) } newFile.Close() err = os.Rename(fpath+".tmp", fpath) if err != nil { fmt.Println(err) //panic(err) } log.Println("下载完成:", filename) } func PathExists(path string) bool { _, err := os.Stat(path) if err == nil { return true } if os.IsNotExist(err) { return false } return false }