这是一个golang爬虫demo 爬去一个美女图片网站的首页所有图片
采用golang 多线程的方式爬取图片 将爬到的图片保存到本地
代码中有用到goquery 网页数据解析框架 chan 控制goroutine 进行下载
/
一个妹子图片网站 请求的 header 必须带着 Referer 否则404 (比较简单的一种反爬虫策略)
用wireshark 抓取浏览器请求图片的数据就可以得到 Referer
//代码不复杂,适合新手学习
var url = "/"
var c chan int
func main() {
(4)
spider()
//testDownLoad()
}
//url->Document->所有图片url->开启多线程进行下载->保存到本地
func spider() {
doc, err := (url)
if err != nil {
(err)
}
urls := ImageRule(doc, match);
("共解析到", len(urls), "图片地址")
c = make(chan int)
for _, s := range urls {
(s)
go downloadImage(s)
}
//可以等待一会儿,留时间给子goroutine 执行
//但是这种方式不怎么靠谱 //直接采用chan 的方式
//(1e9*10)
for i := 0; i < len(urls); i++ {
<-c
}
}
// 单独测试了以下 下载方法
func testDownLoad() {
var url_img = "/uploads/tu/201608/164/";
//var url_img = "/uploads/tu/sm/201601/19/";
downloadImage(url_img)
}
func match(image string) {
(image);
}
func getData(url string) (eader , err error) {
req := buildRequest(url)
resp, err := (req)
defer ()
return (), err
}
// 得到一个网页中所有 ImageUrl
func parseImageUrl(reader ) (res []string, err error) {
doc, err := (reader)
if err != nil {
return nil, err
}
()
ImageRule(doc, func(image string) {
res = append(res, image)
})
return res, nil
}
func ImageRule(doc *, f func(image string)) (urls []string) {
str := make([]string, 0)
//直接找以img 开头的标签 过滤掉不符合规则的url 即可
("img").Each(func(i int, s *) {
url, result := ("src")
if result {
if (url, ".jpg") {
str = append(str, url)
}
}
})
return str
}
//根据url 创建http 请求的 request
//网站有反爬虫策略 wireshark 不解释
func buildRequest(url string) * {
req, err := ("GET", url, nil)
if err != nil {
panic(err)
}
// ("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36")
// ("Cookie", "Hm_lvt_c605a31292b623d214d012ec2a737685=1516111586; Hm_lpvt_c605a31292b623d214d012ec2a737685=1516111613")
//("If-None-Match", "5a309bab-26057")
("Referer", "/")
//("If-Modified-Since", "Wed, 13 Dec 2017 03:16:59 GMT")
return req
}
// 下载图片
func downloadImage(url string) {
fileName := getNameFromUrl(url)
req := buildRequest(url)
= 10 * ;
resp, err := (req)
if err != nil {
("failed download ")
panic(err)
}
if != {
("failed download " + url)
return
}
defer func() {
()
if r := recover(); r != nil {
(r)
}
c <- 0
}()
("begin download " + fileName)
("./images/", 0777)
localFile, _ := ("./images/"+fileName, os.O_CREATE|os.O_RDWR, 0777)
if _, err := (localFile, ); err != nil {
panic("failed save " + fileName)
}
("success download " + fileName)
}
// 判读文件夹是否存在
func isExist(dir string) bool {
_, err := (dir)
if err == nil {
return true
}
return (err)
}
// 通过url 得到图片名字
func getNameFromUrl(url string) string {
arr := (url, "/")
return arr[len(arr)-1]
}
项目地址:点击打开链接
goquery 传送门 //PuerkitoBio/goquery