之前爬虫用python写总是出问题,于是换成了Go来写,大致内容如下:
for ;next_url != first_url; {
count += 1
strBody = getContent(next_url)
re = regexp.MustCompile("photos-view-id-\\d+.html")
next_url = getNextUrl(strBody)
re = regexp.MustCompile("http://xxxx/data/[^\"]+")
pic_url = re.FindAllString(strBody, 2)[1]
filename = fmt.Sprintf("%03d.jpg", count)
go downloadFromUrl(pic_url, save_path + filename)
}
但是这样会有一个问题就是我的downloadFromUrl还没执行完成时,程序已经退出了,导致最后几个文件未下载成功。有什么方法可以等待操作完成之后退出程序的么?
在《Go语言编程》这本书中介绍过。
使用Channel通信来解决,goruntime没有执行完,main就退出的问题。简单示例如下:
package main
import "fmt"
func download(url string, ch chan int) {
fmt.Println(url)
ch <- 1
}
func main() {
urls := []string{
"http://www.a.com/1.gzip",
"http://www.a.com/2.gzip",
"http://www.a.com/3.gzip",
"http://www.a.com/4.gzip",
}
ch := make(chan int, 4)
for _, v := range urls {
go download(v, ch)
}
for i := 0; i < len(urls); i++ {
<-ch
}
fmt.Println("over")
}
参考 @方泽图 的回复,实现方式如下:
var wg sync.WaitGroup
...
for ;next_url != first_url; {
....
filename = fmt.Sprintf("%03d.jpg", count)
wg.Add(1)
go func(pic_url string, saveto string) {
defer wg.Done()
downloadFromUrl(pic_url, saveto)
}(pic_url, saveto)
}
wg.Wait()