目录
- 学习地址:
- 目录站:
- 爬虫概念:
- 工作流程:
- 百度贴吧爬虫实现:
- go实战代码
- 单进程
- 实现过程:
- 并发爬取
- 实现过程:
- 单进程
学习地址:
https://www.bilibili.com/video/BV1Nt411H7sP?p=4
目录站:
https://tieba.baidu.com/f?kw=绝地求生&ie=utf-8&pn=0
https://tieba.baidu.com/f?kw=绝地求生&ie=utf-8&pn=50
https://tieba.baidu.com/f?kw=绝地求生&ie=utf-8&pn=100
爬虫概念:
访问web服务器,获取指定数据信息的一段程序.
工作流程:
- 明确目标Url.
- 发送请求,获取应答数据包.
- 保存,过滤数据.提取有用信息.
- 使用,分析得到数据信息.
百度贴吧爬虫实现:
go实战代码
单进程
实现过程:
- 提示用户指定起始,终止页.创建working函数.
- 使用start,end循环爬取每一页数据.
- 获取第一页的url--下一页=前一页+50.
- 封闭实现HttpGet()函数,爬取一个网页的数据内容,通过result返回.
httpGet/resp.Body.Close/buf:=make(4096)/for{resp.Body.Read(buf)/result += string(buf[:n]) return} - 创建.html文件.使用循环因子i命名.
- 将result写入文件WriteString(result).f.close() 不推荐使用defer.
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
)
// HttpGet ...
func HttpGet(url string) (result string, err error) {
resp, err1 := http.Get(url)
if err1 != nil {
err = err1
return
}
defer resp.Body.Close()
//循环读取网页数据,传出给调用者
buf := make([]byte, 4096)
for {
n, err2 := resp.Body.Read(buf)
if n == 0 {
fmt.Println("读取网页完成")
break
}
if err2 != nil && err2 != io.EOF {
err = err2
return
}
result += string(buf[:n])
}
return
}
func working(start, end int) {
fmt.Printf("正在爬取第%d页到第%d页...\n", start, end)
// 循环爬取第一页的数据
for i := start; i <= end; i++ {
url := "https://tieba.baidu.com/f?kw=%E7%BB%9D%E5%9C%B0%E6%B1%82%E7%94%9F&ie=utf-8&pn=" + strconv.Itoa((i-1)*50)
result, err := HttpGet(url)
if err != nil {
fmt.Println("HttpGet err:", err)
continue
}
// fmt.Println("result=", result)
//将读到的整网页数据,保存为为文件
f, err := os.Create("第 " + strconv.Itoa(i) + " 页.html")
if err != nil {
fmt.Println("Create err:", err)
continue
}
f.WriteString(result)
f.Close()
}
}
func main() {
var start, end int
fmt.Print("请输入爬取的起始页(>=1):")
fmt.Scan(&start)
fmt.Print("请输入爬取的终止页(>=start):")
fmt.Scan(&end)
working(start, end)
}
并发爬取
实现过程:
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
)
// HttpGet ...
func HttpGet(url string, i int) (result string, err error) {
resp, err1 := http.Get(url)
if err1 != nil {
err = err1
return
}
defer resp.Body.Close()
//循环读取网页数据,传出给调用者
buf := make([]byte, 4096)
for {
n, err2 := resp.Body.Read(buf)
if n == 0 {
fmt.Printf("正在读取第 %d 页\n", i)
break
}
if err2 != nil && err2 != io.EOF {
err = err2
return
}
result += string(buf[:n])
}
return
}
//SpiderPage ...
func SpiderPage(i int, page chan int) {
url := "https://tieba.baidu.com/f?kw=%E7%BB%9D%E5%9C%B0%E6%B1%82%E7%94%9F&ie=utf-8&pn=" + strconv.Itoa((i-1)*50)
result, err := HttpGet(url, i)
if err != nil {
fmt.Println("HttpGet err:", err)
return
}
// fmt.Println("result=", result)
//将读到的整网页数据,保存为为文件
f, err := os.Create("第 " + strconv.Itoa(i) + " 页.html")
if err != nil {
fmt.Println("Create err:", err)
return
}
f.WriteString(result)
f.Close()
page <- i
}
func working(start, end int) {
fmt.Printf("正在爬取第%d页到第%d页...\n", start, end)
page := make(chan int)
// 循环爬取第一页的数据
for i := start; i <= end; i++ {
go SpiderPage(i, page)
}
for i := start; i < end; i++ {
fmt.Printf("第 %d 页都页面完成...\n", <-page)
}
}
func main() {
var start, end int
fmt.Print("请输入爬取的起始页(>=1):")
fmt.Scan(&start)
fmt.Print("请输入爬取的终止页(>=start):")
fmt.Scan(&end)
working(start, end)
}