golang

【golang】实现简单爬虫---豆瓣电影前250

2019-07-28  本文已影响0人  七八个星天
package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "regexp"
    "strconv"
)

func main() {
    //起始页,页结束
    var startPage, endPage int
    fmt.Println("请输入起始页>=1")
    fmt.Scan(&startPage)
    fmt.Println("请输入结束页>=起始页")
    fmt.Scan(&endPage)
    startWorking(startPage, endPage)
}
func startWorking(startPage, endPage int) {
    //同步每个go程,每个go程结束,往此通道写入数据,所有go程结束退出程序
    quit := make(chan int)
    for i := startPage; i <= endPage; i++ {
        go getPages(i, quit)
    }
    //从通道中释放数据,次数等于抓取的页数,若循环结束,表示所有页面抓取完成,主程序退出
    for i := startPage; i <= endPage; i++ {
        <-quit
    }
}

/**
爬取单个链接对应的页面
*/
func getPages(i int, quit chan int) {
    //完整的url,因为每页25条数据,所以一次增加25条
    url := "https://movie.douban.com/top250?start=" + strconv.Itoa((i-1)*25) + "&filter="
    //获取指定页面信息
    res, err := http.Get(url)
    if err != nil {
        fmt.Println("http.Get err: ", err)
        return
    }
    //以字符串的形式保存页面响应的body里面的内容
    var str string
    body := res.Body
    buf := make([]byte, 4096)
    //读取页面内容
    for {
        n, err := body.Read(buf)
        if n == 0 {
            break
        }
        if err != nil && err != io.EOF {
            fmt.Println("body.Read err: ", err)
            return
        }
        str += string(buf[:n])
    }
    //提取相关信息
    //提取电影名称的正则表达式
    titleReg := regexp.MustCompile(`<img width="100" alt="(?s:(.*?))"`)
    titles := titleReg.FindAllStringSubmatch(str, -1) //-1表示返回所有匹配的值
    //提取分数
    scoreReg := regexp.MustCompile(`<span class="rating_num" property="v:average">(?s:(.*?))</span>`)
    scores := scoreReg.FindAllStringSubmatch(str, -1)
    //提取评价人数
    peopleNumReg := regexp.MustCompile(`<span>(\d*?)人评价</span>`)
    peopleNums := peopleNumReg.FindAllStringSubmatch(str, -1)
    //创建txt文件,保存提取出来的信息
    createFile(i, titles, scores, peopleNums)
    res.Body.Close()
    //通道写入数据,表示本go程操作完成
    quit <- i
}

/**
创建文件
*/
func createFile(idx int, titles, scores, peopleNums [][]string) {
    //创建文件
    file, err := os.Create("C:/GoProject/file/douban/" + strconv.Itoa(idx) + ".txt")
    if err != nil {
        fmt.Println("os.Create err: ", err)
        return
    }
    //写入项目行
    file.WriteString("电影名称\t\t\t评分\t\t\t评分人数\r\n")
    for i := 0; i < len(titles); i++ {
        title := titles[i][1]
        score := scores[i][1]
        num := peopleNums[i][1]
        //写入标题,形如:1.肖申克的救赎,“\t”表示制表符,“\r\n”表示回车+换行
        file.WriteString(strconv.Itoa((idx-1)*25+i+1) + "." + title + "\t\t\t")
        file.WriteString(score + "\t\t\t")
        file.WriteString(num + "\r\n")
    }
    file.Close()
}

上一篇下一篇

猜你喜欢

热点阅读