欢迎光临
我们一直在努力

go语言学习例子No.4–练习正则爬取图片

代码还是之前的代码

package main
import (
	"io/ioutil"
	"log"
	"net/http"
	"regexp"
)
type pachong struct {
	re  string
	url string
}
func (p *pachong) getinfo() []string { //爬虫结构体的getinfo方法
	res, err := http.Get(p.url)
	if err != nil {
		log.Fatal(err)
	}
	result, err := ioutil.ReadAll(res.Body)
	err = ioutil.WriteFile("abc.html", result, 0777)
        //这里我输出网页源代码看看正则是否错误
	res.Body.Close()
	if err != nil {
		log.Fatal(err)
	}
	re := regexp.MustCompile(p.re)            //匹配正则
	s := re.FindAllString(string(result), -1) //返回字符串切片,-1表示全部,1表示匹配1个,2就匹配2个

	return s
}
func (p *pachong) getstring(s []string) []byte { //爬虫结构体的getstring方法
	var st string
	for _, v := range s {
		st = st + v + "\n" //字符串拼接
	}
	return []byte(st)
}
func main() {
	pa := &pachong{`(?U:src=["']https?://.+\.(jpg|gif|png)["'])`, "https://www.foxzc.com/"}
        //这里使用非贪婪模式,试过几个网站应该是没错,但是有些网站使用了边看边加载的模式就获取不到很多图片
	result := pa.getinfo()
	st := pa.getstring(result) //定义一个字符串变量用来把字符串切片转换成字符串
	//再把字符串转换成字节切片输入到文件
	err := ioutil.WriteFile("abc.txt", st, 0777)
	if err != nil {
		log.Fatal(err)
	}
}

下面是爬取到后下载图片

package main
import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"regexp"
)
type pachong struct {
	re  string//保存正则表达式
	url string//保存网址
}
func (p *pachong) getinfo() []string { //爬虫结构体的getinfo方法
	res, err := http.Get(p.url)
	if err != nil {
		log.Fatal(err)
	}
	result, err := ioutil.ReadAll(res.Body)
	err = ioutil.WriteFile("abc.html", result, 0777)
	res.Body.Close()
	if err != nil {
		log.Fatal(err)
	}
	re := regexp.MustCompile(p.re)            //匹配正则
	s := re.FindAllString(string(result), -1) //返回字符串切片,-1表示全部,1表示匹配1个,2就匹配2个
	return s
}
func (p *pachong) getstring(s []string) []byte { //爬虫结构体的getstring方法,把切片变成字符串拼接起来
	var st string
	for _, v := range s {
		st = st + v + "\n" //字符串拼接
	}
	fmt.Println("获取到", len(s), "条信息")
	return []byte(st)
}
func (p *pachong) downImg(s []string) { //传入获取到的字符串切片
	for _, v := range s {
		//因为获取到的样子是src="https://bbs-
		//多余v[5:]取第5个字符后面的内容
		st := v[5:]
		res, _ := http.Get(st)                  //获取图片地址的对象
		imgBytes, _ := ioutil.ReadAll(res.Body) //获取图片地址的字节流
		res.Body.Close()
		re := regexp.MustCompile(`(?U:[^/]+\.(jpg|gif|png)$)`) //这里是我写的获取文件名
		imgName := re.FindString(st)                           //在regexp包里找到的匹配字符串输出字符串方法
		path := `D:\go\img\` + imgName                         //img文件夹不存在的话会错误,先创建
		err := ioutil.WriteFile(path, imgBytes, 0777)          //保存到文件夹
		if err != nil {
			log.Fatal(err)
		}
	}
}
func main() {
	pa := &pachong{`(?U:src=["']https?://.+\.(jpg|gif|png))`, "http://www.zol.com.cn/"}
	result := pa.getinfo()
	pa.downImg(result)
}

目前为止是同步下载的,我们简陋的修改下变成并发下载

package main
import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"regexp"
	"sync"
)
type pachong struct {
	re  string
	url string
}
func (p *pachong) getinfo() []string { //爬虫结构体的getinfo方法
	res, err := http.Get(p.url)
	if err != nil {
		log.Fatal(err)
	}
	result, err := ioutil.ReadAll(res.Body)
	err = ioutil.WriteFile("abc.html", result, 0777)
	res.Body.Close()
	if err != nil {
		log.Fatal(err)
	}
	re := regexp.MustCompile(p.re)            //匹配正则
	s := re.FindAllString(string(result), -1) //返回字符串切片,-1表示全部,1表示匹配1个,2就匹配2个

	return s
}
func (p *pachong) getstring(s []string) []byte { //爬虫结构体的getstring方法,把切片变成字符串拼接起来
	var st string
	for _, v := range s {
		st = st + v + "\n" //字符串拼接
	}
	fmt.Println("获取到", len(s), "条信息")
	return []byte(st)
}

func (p *pachong) downImg(s []string) { //传入获取到的字符串切片
	for _, v := range s {
		//因为获取到的样子是src="https://bbs-
		//多余v[5:]取第5个字符后面的内容
		st := v[5:]
		res, _ := http.Get(st)                  //获取图片地址的对象
		imgBytes, _ := ioutil.ReadAll(res.Body) //获取图片地址的字节流
		res.Body.Close()
		re := regexp.MustCompile(`(?U:[^/]+\.(jpg|gif|png)$)`) //这里是我写的获取文件名
		imgName := re.FindString(st)                           //在regexp包里找到的匹配字符串输出字符串方法
		path := `D:\go\img\` + imgName                         //img文件夹不存在的话会错误,先创建
		err := ioutil.WriteFile(path, imgBytes, 0777)          //保存到文件夹
		if err != nil {
			log.Fatal(err)
		}
		wg.Done() //程序最后执行.相当于Add(-1)

	}
}
var wg sync.WaitGroup //定义WaitGroup类型
func main() {
	pa := &pachong{`(?U:src=["']https?://.+\.(jpg|gif|png))`, "https://www.gamersky.com/"}
	result := pa.getinfo()
	wg.Add(len(result)) //添加计数器
	go pa.downImg(result)
	wg.Wait() //表示阻塞直到WaitGroup计数器为0
}

上面添加的计数器太多了,我们改下

var wg sync.WaitGroup      //定义WaitGroup类型
func main() {
	pa := &pachong{`(?U:src=["']https?://.+\.(jpg|gif|png))`, "https://www.gamersky.com/"}
	result := pa.getinfo()
	wg.Add(1)//添加1个计数器
	go func() {//匿名函数
		pa.downImg(result)
		wg.Done()
	}()
	wg.Wait()

}

再用Channel,并发同步

var ch = make(chan int) //用channel通道
func main() {
	pa := &pachong{`(?U:src=["']https?://.+\.(jpg|gif|png))`, "https://www.gamersky.com/"}
	result := pa.getinfo()
	go func() {
		//ch <- 123,不能放在这个位置,如果放在这里接收和发送都已经完成,下面的就不一定会执行
		pa.downImg(result)
		ch <- 123
	}()
	<-ch
}
 收藏 (0) 打赏

您可以选择一种方式赞助本站

支付宝扫一扫赞助

微信钱包扫描赞助

未经允许不得转载:家里蹲的狐狸 » go语言学习例子No.4–练习正则爬取图片

分享到: 生成海报
avatar

评论 抢沙发

  • QQ号
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

登录

忘记密码 ?

切换登录

注册

我们将发送一封验证邮件至你的邮箱, 请正确填写以完成账号注册和激活