code.zip download

双向爬取:
横向:以页为单位。
纵向:以一个页面内的条目为单位。

爬取视频信息:

—- 实现流程:
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)
}