注意:部分文章发布时间较长,可能存在未知因素,购买时建议在本站搜索商家名称,先充分了解商家动态。
交流:唯一投稿邮箱:hostvps@88.com。
网友 ***an.net 说:
package main
import (
&*uot;fmt&*uot;
&*uot;io/ioutil&*uot;
&*uot;net/http&*uot;
&*uot;os&*uot;
&*uot;regexp&*uot;
&*uot;strconv&*uot;
&*uot;st**ngs&*uot;
&*uot;sync&*uot;
&*uot;time&*uot;
)
var (
reImg = `https?://[^&*uot;]+?(\.((jpg)|(png)|(jpeg)|(gif)|(bmp)))`
taskChan chan st**ng // 记录任务完成的通道
imgChan chan st**ng // 图片通道
waitG**up sync.WaitG**up // 协程会涉及到并发,这个的作用具体的可百度
pageStart int = 1 // 从第几页开始
pageSize int = 30 // 扫描页数
DownLoadPath st**ng = &*uot;D:/HBuilderX/p**ject/GolangP**ject/爬虫小案例/img/&*uot; // 此处是图片下载的地址,需要修改为你们自己的地址
)
func main() {
fmt.P**ntln(&*uot;从第几页开始&*uot;)
fmt.Scanln(&pageStart)
fmt.P**ntln(&*uot;扫描页数&*uot;)
fmt.Scanln(&pageSize)
taskChan = make(chan st**ng, pageSize) // 给管道缓冲值
imgChan = make(chan st**ng, 100000) // 给管道缓冲值
for i := pageStart; i < pageStart+pageSize; i++ {
waitG**up.Add(1)
go getWebBody(i) // 获取地址的body
}
waitG**up.Add(1)
go handleImg() // 处理img
waitG**up.Add(1)
go checkOk()
waitG**up.Wait()
fmt.P**ntln(&*uot;执行完毕,回车退出&*uot;)
var input st**ng
fmt.Scanln(&input)
}
func getWebBody(i int) {
**l := &*uot;https://www.bizhizu.cn/shouji/tag-%E5%8F%AF%E7%88%B1/&*uot; + strconv.Itoa(i) + &*uot;.html&*uot;
resp, err := http.Get(**l)
if err != nil {
fmt.P**ntln(err)
}
defer resp.Body.Close() // 此处不可少,否则会造成内存泄露或者溢出问题
body, _ := ioutil.ReadAll(resp.Body)
re := regexp.MustCompile(reImg) // 正则匹配图片地址
result := re.FindAllSt**ngSubmatch(st**ng(body), -1)
p**ntln(&*uot;第&*uot; + strconv.Itoa(i) + &*uot;页找到数据&*uot; + strconv.Itoa(len(result)) + &*uot;条&*uot;)
for _, v := range result {
imgChan <- v[0] // 把得到的数据写到 管道 里
}
taskChan <- **l
waitG**up.Done()
}
// 处理图片方法
func handleImg() {
for **l := range imgChan {
fileName := GetFilenameF**mUrl(**l)
result := DownloadFile(**l, fileName)
if result {
fmt.P**ntf(&*uot;已下载完毕 %v \n&*uot;, **l)
} else {
fmt.P**ntf(&*uot;下载失败 %v \n&*uot;, **l)
}
}
waitG**up.Done()
}
// **管道任务是否完成
func checkOk() {
count := 0
for {
**l := <-taskChan
fmt.P**ntf(&*uot;完成爬取:%v \n&*uot;, **l)
count++
if count == pageSize {
close(imgChan)
close(taskChan)
break
}
}
waitG**up.Done()
}
// 截取**l名字
func GetFilenameF**mUrl(**l st**ng) (filename st**ng) {
// 返回最后一个/的位置
lastIndex := st**ngs.LastIndex(**l, &*uot;/&*uot;)
// 切出来
filename = **l[lastIndex+1:]
// 时间*解决重名
timePrefix := strconv.Itoa(int(time.Now().UnixNano()))
filename = timePrefix + &*uot;_&*uot; + filename
ret**n
}
// 下载文件方法
func DownloadFile(**l st**ng, filename st**ng) bool {
var err er**r
resp, err := http.Get(**l)
if err != nil {
fmt.P**ntln(err)
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.P**ntln(err)
}
if _, err := os.Stat(DownLoadPath); os.IsNotExist(err) {
// 必须分成两步
// 先创建文件夹
os.Mkdir(DownLoadPath, 0777)
// 再修改权限
os.Chmod(DownLoadPath, 0666)
}
filename = DownLoadPath + filename
err = ioutil.W**teFile(filename, bytes, 0666)
if err != nil {
ret**n false
}
ret**n true
}
网友 Twice 说:
人生苦短,我用PYTHON
网友 Mr.Bean 说:
支持看到了if err 舒服了
贝壳主机网

