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) }