GO并发爬取视频列表综合案例
双向爬取:
横向:以页为单位。
纵向:以一个页面内的条目为单位。
爬取视频信息:
—- 实现流程:
1. 获取用户输入 起始、终止页、启动 toWork 函数 循环 调用函数 爬取每一个页面
2. 横向爬取url 信息。封装 HttpGet 函数,爬取一个页面所有数据 存入 result 返回
3. 找寻、探索网页 纵向爬取规律。找出“电影名”、“分数”、“评分人数”网页数据特征
4. 分别 对这三部分数据使用 go 正则函数: 1) 解析、编译正则表达式 2) 提取信息 ——> string[1]: 代表没有 匹配参考项内容。
5. 将提取到的数据,按自定义格式写入文件。使用 网页编号命名文件
6. 实现并发。
1) go SpiderPageDB(url) 。
2) 创建 channel 防止主 go 程退出
3) SpiderPageDB 函数末尾,写入 channel
4) 主 go 程 for 读取 channel
package main
import (
"fmt"
"io"
"net/http"
"os"
"regexp"
"strconv"
)
//抓取HTTP页面返回result
func HttpGet(url string)(result string,err error){
resp,err1 := http.Get(url)
if err1 != nil{
err = err1
}
defer resp.Body.Close()
//接收数据
buf := make([]byte,2048)
for{
n,err2 := resp.Body.Read(buf)
if n == 0{
break
}
if err2 != nil && err2 != io.EOF{
err = err2
}
result += string(buf[:n])
}
return
}
func SaveFile(i int,title,point [][]string){
path := "D:\\www\\gostudy\\pachong\\html\\"+strconv.Itoa(i)+".txt"
fp,err:= os.Create(path)
if err != nil{
fmt.Println("文件创建失败",err)
}
defer fp.Close()
for i:=0;i < len(title);i++{
fp.WriteString(strconv.Itoa(i)+"\t"+point[i][1]+"\t"+title[i][3]+"\n")
}
}
func SpiderWeb(i int,f chan int) {
url := "http://imdb.kxapps.com/default.aspx?page=" + strconv.Itoa(i)
result,err := HttpGet(url)
if err != nil{
fmt.Printf("页码%d出错跳过",i)
return
}
//使用正则表达式提取
ret := regexp.MustCompile(`class="(c_blue)?(c_fff)?">(.*) .*`)
// 提取需要的信息
title := ret.FindAllStringSubmatch(result, -1)
ret2 := regexp.MustCompile(``)
point := ret2.FindAllStringSubmatch(result, -1)
SaveFile(i,title,point)
//通道发送
f <- i
}
func working(start int,end int){
fmt.Printf("准备爬取页码%d-%d\n",start,end)
//创建通道
var f = make(chan int)
for i:=start;i <= end ;i++{
//并发执行
go SpiderWeb(i,f)
}
for i:=start;i <= end ;i++ {
fmt.Printf("正在爬取%d页...\n", <-f)
}
}
func main() {
var start,end int
fmt.Print("请输入开始页码:")
fmt.Scan(&start)
fmt.Print("请输入结束页码:")
fmt.Scan(&end)
working(start,end)
}