最近学完go了想实战一下,于是就试试并发爬取数据吧
找了一个网站 优图
内容涉及到了
正则
时间
匿名函数线程的
下边是代码
package main import ( "fmt" "io/ioutil" "math/rand" "net/http" "os" "regexp" "strconv" "strings" "sync" "time" ) /* //爬取图片 //http://www.uutu.me/index.php?c=Article&id=6671 <div align="center"> <a href="http://www.uutu.me/index.php?c=Article&id=6671&p=3"> <img class="img-responsive" alt="[IMiss]爱蜜社 2018.11.30 Vol.310 王雨纯" src="http://d.kancaijing.com.cn/attach/2020-01-17/1579252699Pphy.jpg" title="点击查看下一张" border="0"><br> <p>[IMiss]爱蜜社 Vol.310 王雨纯</p> <p>(点击图片查看下一页) </p> </a> </div> */ var ( ch = make(chan []string,10) chns = make(chan int,100) downAsyncWG1 sync.WaitGroup downAsyncWG2 sync.WaitGroup RMT sync.Mutex Url = "http://www.uutu.me/index.php?c=Article&id=6671" //`<img[\s\S]+?data-original="(http[\s\S]+?)"` re = `align="center"[\s\S]+?href="(http[\s\S]+?)">[\s\S]+?class="img-responsive"[\s\S]+?alt="([\s\S]+?)"[\s\S]+?src="(http[\s\S]+?\.(jpg|png))"` //`1[345678]\d{9}` ) //获取随机数 func getRandNum() int { RMT.Lock() <-time.After(1 * time.Nanosecond) r := rand.New(rand.NewSource(time.Now().UnixNano())) ret := int(time.Now().UnixNano()) - r.Intn(int(int(time.Now().Unix()))) RMT.Unlock() return ret } //文件名 func getFileName(strimg string) string { strimg = strings.Replace(strimg, " ", "_", -1) str := strconv.Itoa(int(time.Now().UnixNano())) str2 := `E:\Go\src\Tools\分布式爬虫\img_103\` + strimg + "_" + str + "_" + strconv.Itoa(getRandNum()) + ".jpg" return str2 } func handErrs(err error, wen string) { if err != nil { fmt.Println(wen, err.Error()) os.Exit(1) } } func getUrlHtml(str string) string { resp, err := http.Get(str) defer resp.Body.Close() handErrs(err, "url") bytes, _ := ioutil.ReadAll(resp.Body) //handErrs(err, "解析返回错内容") return string(bytes) } // 传入url 和 正则规则 返回地址列表 func getImageUrl(url,reStr string) (images []string) { html := getUrlHtml(url) str := regexp.MustCompile(reStr) wangyi := str.FindAllStringSubmatch(html,-1) //fmt.Println(wangyi) //images = make([]string,0) for _,link := range wangyi{ images = append(images,link[1],link[2],link[3]) //下一张链接 名字 图片地址 } return } //下载 参数 url func downloads(str []string) { fmt.Println("开始下载"+ str[1] +"........") resp, err := http.Get(str[2]) defer resp.Body.Close() handErrs(err, "downloads-url") imgbytes, err := ioutil.ReadAll(resp.Body) if err != nil{ fmt.Println("报错了:", err.Error()) time.Sleep(time.Hour) return } handErrs(err, "解析返回错内容") filename := getFileName(str[1]) err = ioutil.WriteFile(filename, imgbytes, 0777) handErrs(err, "ioutil.WriteFile") fmt.Println(str[1] + "下载完成........") } func downAsync(str []string) { downAsyncWG2.Add(1) go func(str []string) { downloads(str) downAsyncWG2.Done() }(str) } func down(Url string) { downAsyncWG1.Add(1) go func() { aaaa(Url) downAsyncWG1.Done() }() downAsyncWG1.Wait() } func aaaa(Url string) { arr := getImageUrl(Url,re) fmt.Println(arr[0],arr[1],arr[2]) ch <- arr down(arr[0]) } func main() { go func() { for { select { case aa := <-ch : fmt.Println(aa) downAsync(aa) } } }() down(Url) downAsyncWG2.Wait() }
程序员,产品
8.7
PHP Go 前端
JwCode
渐悟分享