Go语言爬虫豆瓣电影小项目

目的:以豆瓣电影为例,爬取整个豆瓣电影静态页面信息

1.获取页面信息

go语言提供了httplib库能够获取静态页面的信息

  movieHtml:=httplib.Get("http://douban.com/")

2.分析页面内容,用正则表达式匹配出相应的信息

比如匹配导演信息
该链接的标签

<a href="/celebrity/1025315/" rel="v:directedBy">彼得·海姆斯</a>

写一个model去匹配

//获取导演信息
func GetMovieDirector(movieHtml string) string{
	if movieHtml==""{
		return ""
	}else{
		reg:=regexp.MustCompile(`<a.*?rel="v:directedBy">(.*?)</a>`)
		result:=reg.FindAllStringSubmatch(movieHtml,-1)
		if len(result)==0{
			return ""
		}
		director:=""
		for i,_:=range  result{
			director+=result[i][1]+" "
		}
		return director
	}
}

其他的信息也是如此,主要是正则表达式的运行,这样我们就能够得到一个电影的完整的信息了
获得后存入数据库就行了

3.制作爬虫

上面的是获取一个页面信息,那么怎么自动获得多个信息?
我们知道每个页面有好多个链接能够链接到其他页面,那么在爬取一个页面时候获取该页面的页面信息不就行了。那么我们可以设置一个爬取队列,开始先入队一个初始url,然后爬取该页面信息,爬取完成后在爬取该页面的链接,然后存入到爬取队列,如此循环。然而我们发现,很多链接是重复的,所以设置一个集合,存储爬取的页面,然后每次爬取前检测该url是否已经在爬取完成的集合中,如此便可实现一个简单爬虫。这里是用redis实现的消息队列。

爬虫流程代码

package controllers

import (
	"crawl_movie/models"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/httplib"
	"strings"
	"time"
)

type CrawlMovieController struct {
	beego.Controller
}
func (c *CrawlMovieController) Get(){
	//连接redis
	models.ConnectRedis("127.0.0.1:6379")

	sUrl:="https://movie.douban.com/subject/33393084/?tag=热门&amp;from=gaia_video"
	//存储电影信息
	var movieInfo models.MovieInfo
	//把初始url加入队列
	models.PutinQueue(sUrl)

	for{
		lenth:=models.GetQueueLength()
		//如果队列为空,停止
		if lenth==0{
			break
		}
		//成功获取到url
		sUrl=models.PopfromQueue()
		if models.IsVisit(sUrl){
			continue
		}
		movieHtml:=httplib.Get(sUrl)
		//将网页html转换为string
		sMovieHtml,err:=movieHtml.String()
		if err!=nil{
			c.Ctx.WriteString(fmt.Sprintf("err:%v\n",err))
		}


		movieInfo.Movie_name=models.GetMovieName(sMovieHtml)
		//如果当前链接是电影,提取出电影信息并入库
		if movieInfo.Movie_name!=""{
			c.Ctx.WriteString("正在从"+sUrl+"爬取电影"+movieInfo.Movie_name+"\n")
			movieInfo.Movie_release_time=models.GetMovieReleaseTime(sMovieHtml)
			movieInfo.Movie_director=models.GetMovieDirector(sMovieHtml)
			movieInfo.Movie_main_character=models.GetMainCharacter(sMovieHtml)
			movieInfo.Movie_on_time=models.GetOnTime(sMovieHtml)
			movieInfo.Movie_country=models.GetMovieCountry(sMovieHtml)
			movieInfo.Movie_type=models.GetMovieType(sMovieHtml)
			movieInfo.Movie_writer=models.GetMovieWriter(sMovieHtml)
			movieInfo.Movie_grade=models.GetMovieMark(sMovieHtml)
			movieInfo.Movie_length=models.GetMovieLength(sMovieHtml)
			movieInfo.Movie_introduction=models.GetMovieIntroduction(sMovieHtml)
			movieInfo.Movie_language=models.GetMovieLanguage(sMovieHtml)
			movieInfo.Movie_other_name=models.GetMovieOtherName(sMovieHtml)
			/*c.Ctx.WriteString(movieInfo.Movie_release_time+" ")
			c.Ctx.WriteString(movieInfo.Movie_director+" ")
			c.Ctx.WriteString(movieInfo.Movie_writer+" ")
			c.Ctx.WriteString(movieInfo.Movie_main_character+" ")
			c.Ctx.WriteString(movieInfo.Movie_type+" ")
			c.Ctx.WriteString(movieInfo.Movie_country+" ")
			c.Ctx.WriteString(movieInfo.Movie_on_time+" ")
			c.Ctx.WriteString(movieInfo.Movie_length+" ")
			c.Ctx.WriteString(movieInfo.Movie_grade+" ")
			c.Ctx.WriteString(movieInfo.Movie_introduction+" ")
			c.Ctx.WriteString(movieInfo.Movie_language+" ")
			c.Ctx.WriteString(movieInfo.Movie_other_name+" ")*/
			_,err:=models.AddMovie(&movieInfo)
			if err!=nil{
				panic(err)
			}else{
				c.Ctx.WriteString(sUrl+"爬取完成\n")
			}

		}
		//获取链接中的url并加入到队列中
		movies:=models.GetMovieUrls(sMovieHtml)
		//c.Ctx.WriteString(fmt.Sprintf("%v",movies))
		for _,url:=range movies{
			url=strings.Trim(url,`"`)

			models.PutinQueue(url)
			//fmt.Println(i,":",url)
		}
		//将访问过的sUrl记录
		models.AddToSet(sUrl)
		//每次爬完间隔一会,防止网站封禁你的ip
		time.Sleep(2)
		//c.Ctx.WriteString(sMovieHtml)
	}
	c.Ctx.WriteString("end of crawling")


}



在这里插入图片描述
redis队列:
在这里插入图片描述
数据库:
在这里插入图片描述
爬取信息在这里插入图片描述
可以发现在不停的爬取,爬取过程会遇到各种问题,有时候爬着爬着不动了,可能最后全是网站的无用链接了,这时候换个链接继续爬;爬的太频繁一般网站会封禁你一段时间的ip,所以最好还是控制好爬取速度。
项目地址:https://github.com/rj2017211811/crawlMovie

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值