GO语言
01GO基础-001GO语言简介
01GO基础-002语言环境安装
01GO基础-003Go 语言结构
01GO基础-004Go 语言基础语法1
01GO基础-004Go 语言基础语法2
01GO基础-004Go 语言基础语法3
01GO基础-005Go 语言数据类型
01GO基础-006Go 语言变量
01GO基础-007Go 语言常量
01GO基础-008Go 语言运算符
01GO基础-009条件语句
01GO基础-010循环语句
01GO基础-011函数
01GO基础-012变量作用域
01GO基础-013数组
01GO基础-014指针
01GO基础-015结构体
01GO基础-016切片
01GO基础-017范围(Range)
01GO基础-018Map
01GO基础-019递归函数
01GO基础-020类型转换
01GO基础-021接口
01GO基础-022异常处理
01GO基础-023并发
01GO基础-024strings
01GO基础-025可变参数
01GO基础-026接口2
01GO基础-027异常处理2
01GO基础-028sync包详解
01GO基础-029Context
02GO进阶001包
02GO进阶002init()函数
02GO进阶003包的注意点
02GO进阶003使用go module导入本地包
02GO进阶004 time包
02GO进阶005 file操作
02GO进阶006 io操作
02GO进阶007 os包(文件 I/O、文件属性、目录与链接、创建和移除链接)
02GO进阶008复制文件
02GO进阶009断点续传
02GO进阶010 bufio包
02GO进阶011ioutil包
02GO进阶012遍历文件夹
02GO进阶013并发编程介绍
02GO进阶014Goroutine协程
02GO进阶015 GPM
02GO进阶016 runtime包
02GO进阶017 Channel
02GO进阶018 Goroutine池
02GO进阶019 定时器
02GO进阶020 select
02GO进阶021并发安全和锁
02GO进阶022sync
02GO进阶023原子操作
02GO进阶024 GMP原理与调度
02GO进阶025爬虫小案例
02GO进阶026 面向对象-匿名字段
02GO进阶026 面向对象-接口
02GO进阶027网络编程-互联网协议介绍
02GO进阶027网络编程-socket
02GO进阶027网络编程-http编程
02GO进阶027网络编程-websocket编程
02GO进阶028数据操作-MYSQL
02GO进阶028数据操作-REDIS
02GO进阶028数据操作-RTCD
02GO进阶028数据操作-ZOOKEEPER
02GO进阶028数据操作-KAFKA
02GO进阶028数据操作-RabbitMQ
02GO进阶028数据操作-ElasticSearch
02GO进阶028数据操作-NSQ
02GO进阶028数据操作-memcached
02GO进阶028数据操作-GORM
02GO进阶029beego框架-安装
02GO进阶029beego框架-快速入门
02GO进阶029beego框架-MVC架构介绍-controller设计-参数配置
02GO进阶029beego框架-MVC架构介绍-controller设计-路由设置
02GO进阶029beego框架-MVC架构介绍-controller设计-控制器函数
02GO进阶029beego框架-MVC架构介绍-controller设计-XSRF过滤
02GO进阶029beego框架-MVC架构介绍-controller设计-请求数据处理
02GO进阶029beego框架-MVC架构介绍-controller设计-Session控制
02GO进阶029beego框架-MVC架构介绍-controller设计-过滤器
02GO进阶029beego框架-MVC架构介绍-controller设计-Flash数据
02GO进阶029beego框架-MVC架构介绍-controller设计-URL构建
02GO进阶029beego框架-MVC架构介绍-controller设计-多种格式数据输出
02GO进阶029beego框架-MVC架构介绍-controller设计-表单数据验证
02GO进阶029beego框架-MVC架构介绍-controller设计-错误处理
02GO进阶029beego框架-MVC架构介绍-controller设计-日志处理
02GO进阶029beego框架-MVC架构介绍-model设计-概述
02GO进阶029beego框架-MVC架构介绍-model设计-CRUD操作
02GO进阶029beego框架-MVC架构介绍-model设计-高级查询
02GO进阶029beego框架-MVC架构介绍-model设计-原生SQL查询
02GO进阶029beego框架-MVC架构介绍-model设计-构造查询
02GO进阶029beego框架-MVC架构介绍-model设计-事务处理
02GO进阶029beego框架-MVC架构介绍-model设计-模型定义
02GO进阶029beego框架-MVC架构介绍-model设计-命令模式
02GO进阶029beego框架-MVC架构介绍-model设计-测试用例
02GO进阶029beego框架-MVC架构介绍-view设计-beego 模板语法指南
02GO进阶029beego框架-MVC架构介绍-view设计-模板处理
02GO进阶029beego框架-MVC架构介绍-view设计-其他
本文档使用 MrDoc 发布
-
+
首页
02GO进阶025爬虫小案例
1.1.1. 爬虫步骤 明确目标(确定在哪个网站搜索) 爬(爬下内容) 取(筛选想要的) 处理数据(按照你的想法去处理) ```go package main import ( "fmt" "io/ioutil" "net/http" "regexp" ) //这个只是一个简单的版本只是获取QQ邮箱并且没有进行封装操作,另外爬出来的数据也没有进行去重操作 var ( // \d是数字 reQQEmail = `(\d+)@qq.com` ) // 爬邮箱 func GetEmail() { // 1.去网站拿数据 resp, err := http.Get("https://tieba.baidu.com/p/6051076813?red_tag=1573533731") HandleError(err, "http.Get url") defer resp.Body.Close() // 2.读取页面内容 pageBytes, err := ioutil.ReadAll(resp.Body) HandleError(err, "ioutil.ReadAll") // 字节转字符串 pageStr := string(pageBytes) //fmt.Println(pageStr) // 3.过滤数据,过滤qq邮箱 re := regexp.MustCompile(reQQEmail) // -1代表取全部 results := re.FindAllStringSubmatch(pageStr, -1) //fmt.Println(results) // 遍历结果 for _, result := range results { fmt.Println("email:", result[0]) fmt.Println("qq:", result[1]) } } // 处理异常 func HandleError(err error, why string) { if err != nil { fmt.Println(why, err) } } func main() { GetEmail() } ``` 1.1.2. 正则表达式 文档:https://studygolang.com/pkgdoc API re := regexp.MustCompile(reStr),传入正则表达式,得到正则表达式对象 ret := re.FindAllStringSubmatch(srcStr,-1):用正则对象,获取页面页面,srcStr是页面内容,-1代表取全部 爬邮箱 方法抽取 爬超链接 爬手机号 http://www.zhaohaowang.com/ 如果连接失效了自己找一个有手机号的就好了 爬身份证号 http://henan.qq.com/a/20171107/069413.htm 如果连接失效了自己找一个就好了 爬图片链接 ```go package main import ( "fmt" "io/ioutil" "net/http" "regexp" ) var ( // w代表大小写字母+数字+下划线 reEmail = `\w+@\w+\.\w+` // s?有或者没有s // +代表出1次或多次 //\s\S各种字符 // +?代表贪婪模式 reLinke = `href="(https?://[\s\S]+?)"` rePhone = `1[3456789]\d\s?\d{4}\s?\d{4}` reIdcard = `[123456789]\d{5}((19\d{2})|(20[01]\d))((0[1-9])|(1[012]))((0[1-9])|([12]\d)|(3[01]))\d{3}[\dXx]` reImg = `https?://[^"]+?(\.((jpg)|(png)|(jpeg)|(gif)|(bmp)))` ) // 处理异常 func HandleError(err error, why string) { if err != nil { fmt.Println(why, err) } } func GetEmail2(url string) { pageStr := GetPageStr(url) re := regexp.MustCompile(reEmail) results := re.FindAllStringSubmatch(pageStr, -1) for _, result := range results { fmt.Println(result) } } // 抽取根据url获取内容 func GetPageStr(url string) (pageStr string) { resp, err := http.Get(url) HandleError(err, "http.Get url") defer resp.Body.Close() // 2.读取页面内容 pageBytes, err := ioutil.ReadAll(resp.Body) HandleError(err, "ioutil.ReadAll") // 字节转字符串 pageStr = string(pageBytes) return pageStr } func main() { // 2.抽取的爬邮箱 // GetEmail2("https://tieba.baidu.com/p/6051076813?red_tag=1573533731") // 3.爬链接 //GetLink("http://www.baidu.com/s?wd=%E8%B4%B4%E5%90%A7%20%E7%95%99%E4%B8%8B%E9%82%AE%E7%AE%B1&rsv_spt=1&rsv_iqid=0x98ace53400003985&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=ib&rsv_sug2=0&inputT=5197&rsv_sug4=6345") // 4.爬手机号 //GetPhone("https://www.zhaohaowang.com/") // 5.爬身份证号 //GetIdCard("https://henan.qq.com/a/20171107/069413.htm") // 6.爬图片 // GetImg("http://image.baidu.com/search/index?tn=baiduimage&ps=1&ct=201326592&lm=-1&cl=2&nc=1&ie=utf-8&word=%E7%BE%8E%E5%A5%B3") } func GetIdCard(url string) { pageStr := GetPageStr(url) re := regexp.MustCompile(reIdcard) results := re.FindAllStringSubmatch(pageStr, -1) for _, result := range results { fmt.Println(result) } } // 爬链接 func GetLink(url string) { pageStr := GetPageStr(url) re := regexp.MustCompile(reLinke) results := re.FindAllStringSubmatch(pageStr, -1) for _, result := range results { fmt.Println(result[1]) } } //爬手机号 func GetPhone(url string) { pageStr := GetPageStr(url) re := regexp.MustCompile(rePhone) results := re.FindAllStringSubmatch(pageStr, -1) for _, result := range results { fmt.Println(result) } } func GetImg(url string) { pageStr := GetPageStr(url) re := regexp.MustCompile(reImg) results := re.FindAllStringSubmatch(pageStr, -1) for _, result := range results { fmt.Println(result[0]) } } ``` 1.1.3. 并发爬取美图 下面的两个是即将要爬的网站,如果网址失效自己换一个就好了 https://www.bizhizu.cn/shouji/tag-%E5%8F%AF%E7%88%B1/1.html ```go package main import ( "fmt" "io/ioutil" "net/http" "regexp" "strconv" "strings" "sync" "time" ) func HandleError(err error, why string) { if err != nil { fmt.Println(why, err) } } // 下载图片,传入的是图片叫什么 func DownloadFile(url string, filename string) (ok bool) { resp, err := http.Get(url) HandleError(err, "http.get.url") defer resp.Body.Close() bytes, err := ioutil.ReadAll(resp.Body) HandleError(err, "resp.body") filename = "E:/topgoer.com/src/github.com/student/3.0/img/" + filename // 写出数据 err = ioutil.WriteFile(filename, bytes, 0666) if err != nil { return false } else { return true } } // 并发爬思路: // 1.初始化数据管道 // 2.爬虫写出:26个协程向管道中添加图片链接 // 3.任务统计协程:检查26个任务是否都完成,完成则关闭数据管道 // 4.下载协程:从管道里读取链接并下载 var ( // 存放图片链接的数据管道 chanImageUrls chan string waitGroup sync.WaitGroup // 用于监控协程 chanTask chan string reImg = `https?://[^"]+?(\.((jpg)|(png)|(jpeg)|(gif)|(bmp)))` ) func main() { // myTest() // DownloadFile("http://i1.shaodiyejin.com/uploads/tu/201909/10242/e5794daf58_4.jpg", "1.jpg") // 1.初始化管道 chanImageUrls = make(chan string, 1000000) chanTask = make(chan string, 26) // 2.爬虫协程 for i := 1; i < 27; i++ { waitGroup.Add(1) go getImgUrls("https://www.bizhizu.cn/shouji/tag-%E5%8F%AF%E7%88%B1/" + strconv.Itoa(i) + ".html") } // 3.任务统计协程,统计26个任务是否都完成,完成则关闭管道 waitGroup.Add(1) go CheckOK() // 4.下载协程:从管道中读取链接并下载 for i := 0; i < 5; i++ { waitGroup.Add(1) go DownloadImg() } waitGroup.Wait() } // 下载图片 func DownloadImg() { for url := range chanImageUrls { filename := GetFilenameFromUrl(url) ok := DownloadFile(url, filename) if ok { fmt.Printf("%s 下载成功\n", filename) } else { fmt.Printf("%s 下载失败\n", filename) } } waitGroup.Done() } // 截取url名字 func GetFilenameFromUrl(url string) (filename string) { // 返回最后一个/的位置 lastIndex := strings.LastIndex(url, "/") // 切出来 filename = url[lastIndex+1:] // 时间戳解决重名 timePrefix := strconv.Itoa(int(time.Now().UnixNano())) filename = timePrefix + "_" + filename return } // 任务统计协程 func CheckOK() { var count int for { url := <-chanTask fmt.Printf("%s 完成了爬取任务\n", url) count++ if count == 26 { close(chanImageUrls) break } } waitGroup.Done() } // 爬图片链接到管道 // url是传的整页链接 func getImgUrls(url string) { urls := getImgs(url) // 遍历切片里所有链接,存入数据管道 for _, url := range urls { chanImageUrls <- url } // 标识当前协程完成 // 每完成一个任务,写一条数据 // 用于监控协程知道已经完成了几个任务 chanTask <- url waitGroup.Done() } // 获取当前页图片链接 func getImgs(url string) (urls []string) { pageStr := GetPageStr(url) re := regexp.MustCompile(reImg) results := re.FindAllStringSubmatch(pageStr, -1) fmt.Printf("共找到%d条结果\n", len(results)) for _, result := range results { url := result[0] urls = append(urls, url) } return } // 抽取根据url获取内容 func GetPageStr(url string) (pageStr string) { resp, err := http.Get(url) HandleError(err, "http.Get url") defer resp.Body.Close() // 2.读取页面内容 pageBytes, err := ioutil.ReadAll(resp.Body) HandleError(err, "ioutil.ReadAll") // 字节转字符串 pageStr = string(pageBytes) return pageStr } ```
admin
2024年12月25日 10:10
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码