内容简介:版权声明:本文为博主尹成联系QQ77025077,微信18510341407原创文章,欢迎转载侵权不究。 https://blog.csdn.net/yincheng01/article/details/84134018
版权声明:本文为博主尹成联系QQ77025077,微信18510341407原创文章,欢迎转载侵权不究。 https://blog.csdn.net/yincheng01/article/details/84134018
导入类库
import ( "fmt" "regexp" "net/http" "io/ioutil" "strings" "sync" "time" "strconv" )
定义全局数据
var ( //存放图片链接 chanImgUrls chan string //存放147个任务是否已完成 chanTask chan string waitGroup sync.WaitGroup )
爬取一个页面上的全部图片链接,返回结果切片
func SpiderPrettyImg(url string) (urls []string) {
pageStr := GetPageStr(url)
//fmt.Println(pageStr)
re := regexp.MustCompile(reImg)
results := re.FindAllStringSubmatch(pageStr, -1)
fmt.Printf("共找到%d条结果:\n", len(results))
for _, result := range results {
url := result[1]
fmt.Println(url)
urls = append(urls, url)
}
return
}
从url中提取文件名称
func GetFilenameFromUrl(url string, dirPath string) (filename string) {
lastIndex := strings.LastIndex(url, "/")
filename = url[lastIndex+1:]
timePrefix := strconv.Itoa(int(time.Now().UnixNano()))
filename = timePrefix + "_" + filename
filename = dirPath + filename
//fmt.Println(fileName)
return
}
下载url对应的文件到指定路径
func DownloadFile(url string, filename string) (ok bool) {
resp, err := http.Get(url)
if err != nil {
HandleError(err, "http.Get(url)")
return
}
defer resp.Body.Close()
//ioutil.ReadAll(resp.Body)read tcp 192.168.20.50:57178->175.6.244.4:80: wsarecv:
// An existing connection was forcibly closed by the remote host.
fBytes, e := ioutil.ReadAll(resp.Body)
HandleError(e, "ioutil.ReadAll(resp.Body)")
err = ioutil.WriteFile(filename, fBytes, 0644)
HandleError(err, "http.Get(url)")
if err != nil {
return false
} else {
return true
}
}
爬取一个页面下的所有图片链接,并丢入全局待下载数据管道
func SpiderImgUrls(url string) {
//获取一个页面下的所有图片链接
urls := SpiderPrettyImg(url)
//将所有图片超链接丢入数据管道
for _, url := range urls {
chanImgUrls <- url
}
//通知当前协程任务完成
chanTask <- url
waitGroup.Done()
}
同步下载图片链接管道中的所有图片
func DownloadImg() {
for url := range chanImgUrls {
filename := GetFilenameFromUrl(url, "D:/BJBlockChain1801/demos/W4/day4/img/")
ok := DownloadFile(url, filename)
if ok {
fmt.Printf("%s下载成功!\n", filename)
} else {
fmt.Printf("%s下载失败!!!!!!!!!!!!\n", filename)
}
}
waitGroup.Done()
}
检查147个任务是否全部完成,完成则关闭数据管道
func CheckIfAllSpidersOk() {
var count int
for {
url := <-chanTask
fmt.Printf("%s完成爬取任务\n", url)
count ++
if count == 147 {
close(chanImgUrls)
break
}
}
waitGroup.Done()
}
主程序
func main() {
//初始化数据管道
chanImgUrls = make(chan string, 1000000)
chanTask = make(chan string, 147)
//爬虫协程:源源不断地往管道中添加图片链接
for i := 1; i < 148; i++ {
waitGroup.Add(1)
go SpiderImgUrls("http://www.umei.cc/tags/meinv_" + strconv.Itoa(i) + ".htm")
}
//开辟任务统计协程,如果147个任务全部完成,则关闭数据管道
waitGroup.Add(1)
go CheckIfAllSpidersOk()
//下载协程:源源不断地从管道中读取地址并下载
for i := 0; i < 10; i++ {
waitGroup.Add(1)
go DownloadImg()
}
waitGroup.Wait()
}
学院 Go 语言视频主页
https://edu.csdn.net/lecturer/1928以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- GoLang - 并发版爬虫
- golang练手小项目系列(2)-并发爬虫
- Golang 并发爬虫 爬取某著名游戏媒体
- Golang实现简单爬虫框架(3)——简单并发版
- 50行代码实现一个并发的 Python 爬虫程序
- Golang实现简单爬虫框架(4)——队列实现并发任务调度
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
别怕,Excel VBA其实很简单
Excel之家 (Excel Home) / 人民邮电出版社 / 2012-10-1 / 49.00元
《别怕,excel vba其实很简单》考虑到大多数读者没有编程基础的实际情况,用浅显易懂的语言和生动形象的比喻,并配合大量插画,介绍excel中看似复杂的概念和代码、从简单的宏录制、vba编程环境和基础语法的介绍,到常用对象的操作与控制、excel事件的调用与控制、用户界面设计、代码调试与优化、都进行了形象的介绍。 《别怕,excel vba其实很简单》适合想提高工作效率的办公人员,特别是经......一起来看看 《别怕,Excel VBA其实很简单》 这本书的介绍吧!