学习了一段时间golang,又参考课程学习了beego开发网站爬虫,项目的目录结构是:

采集的目标是豆瓣网电影,入口地址是:https://movie.douban.com/subject/1900841/?from=subject-page

数据结果

数据表结构

CREATE TABLE `movie_info` (
`id` int() unsigned NOT NULL AUTO_INCREMENT,
`movie_id` int() unsigned NOT NULL COMMENT '电影id',
`movie_name` varchar() DEFAULT NULL COMMENT '电影名称',
`movie_pic` varchar() DEFAULT NULL COMMENT '电影图片',
`movie_director` varchar() DEFAULT NULL COMMENT '电影导演',
`movie_writer` varchar() DEFAULT NULL COMMENT '电影编剧',
`movie_country` varchar() DEFAULT NULL COMMENT '电影产地',
`movie_language` varchar() DEFAULT NULL COMMENT '电影语言',
`movie_main_character` varchar() DEFAULT NULL COMMENT '电影主演',
`movie_type` varchar() DEFAULT NULL COMMENT '电影类型',
`movie_on_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '电影上映时间',
`movie_span` varchar() DEFAULT NULL COMMENT '电影时长',
`movie_grade` varchar() DEFAULT NULL COMMENT '电影评分',
`remark` varchar() DEFAULT '' COMMENT '备注',
`create_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
`modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`status` tinyint() DEFAULT '',
PRIMARY KEY (`id`),
KEY `idx_movie_id` (`movie_id`),
KEY `idx_create_time` (`create_time`),
KEY `idx_modify_time` (`modify_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='电影信息表';

文件

app.conf文件,用来配置数据库

appname = mypro
httpport =
runmode = dev
dbhost = 127.0.0.1
dbport =
dbname = myblog
dbuser = root
dbpwd = root

路由文件router.go

//router.go文件
package routers import (
"mypro/controllers"
"github.com/astaxie/beego"
) func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/collection", &controllers.CollectionController{})
}

控制器下文件

package controllers

import (
"fmt"
"github.com/astaxie/beego"
"github.com/astaxie/beego/httplib"
"mypro/models"
"time"
) type CollectionController struct {
beego.Controller
} func (c *CollectionController) Get() { sUrl := "https://movie.douban.com/subject/1900841/?from=subject-page" //这里作为入口
models.PutinUrlQueue(sUrl)
models.ConnectRedis("127.0.0.1:6379") //连接redis for {
var MovieInfo models.MovieInfo
UrlQueueLength := models.GetQueueLength()
c.Ctx.WriteString(fmt.Sprintf("---%v---", UrlQueueLength))
if UrlQueueLength == {
break;
} //从队列中取出url
sUrl = models.PopfromQueue() //如果url在集合里,那么过滤掉
if models.IsVisit(sUrl) {
continue
} rsp := httplib.Get(sUrl)
//设置User-agent以及cookie是为了防止 豆瓣网的 403
rsp.Header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0")
rsp.Header("Cookie", `bid=gFP9qSgGTfA; __utma=30149280.1124851270.1482153600.1483055851.1483064193.8; __utmz=30149280.1482971588.4.2.utmcsr=douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/; ll=""; _pk_ref..4cf6=%5B%%%2C%%%2C1483064193%2C%22https%3A%2F%2Fwww.douban.com%2F%%5D; _pk_id..4cf6=5afcf5e5496eab22.1482413017.7.1483066280.1483057909.; __utma=223695111.1636117731.1482413017.1483055857.1483064193.7; __utmz=223695111.1483055857.6.5.utmcsr=douban.com|utmccn=(referral)|utmcmd=referral|utmcct=/; _vwo_uuid_v2=BDC2DBEDF8958EC838F9D9394CC5D9A0|2cc6ef7952be8c2d5408cb7c8cce2684; ap=; viewed=""; gr_user_id=e5c932fc-2af6--8a4f-5d696f34570b; __utmc=; __utmc=; _pk_ses..4cf6=*; __utmb=30149280.0.10.1483064193; __utmb=223695111.0.10.1483064193`)
sMovieHtml, err := rsp.String() // fmt.Print(sMovieHtml) if err != nil {
panic(err)
} MovieInfo.Movie_name = models.GetMovieName(sMovieHtml) // fmt.Print(MoveInfo.Movie_name) if MovieInfo.Movie_name != "" { //如果为空,则说明不是电影,如果不为空,则是电影
//获取电影导演
MovieInfo.Movie_director = models.GetMovieDirector(sMovieHtml)
//获取主演
MovieInfo.Movie_main_character = models.GetMovieMainCharacters(sMovieHtml)
//电影类型
MovieInfo.Movie_type = models.GetMovieGenre(sMovieHtml)
//上映时间
MovieInfo.Movie_on_time = models.GetMovieOnTime(sMovieHtml)
//评分
MovieInfo.Movie_grade = models.GetMovieGrade(sMovieHtml)
//时长
MovieInfo.Movie_span = models.GetMovieRunningTime(sMovieHtml)
// c.Ctx.WriteString(fmt.Sprintf("%v", MovieInfo))
//入库
//models.AddMovieToDb(&MovieInfo)
//fmt.Println(MovieInfo)
//fmt.Println(&MovieInfo)
//os.Exit(1)
id, err := models.AddMovieToDb(&MovieInfo)
fmt.Println(err)
c.Ctx.WriteString(fmt.Sprintf("%v", id))
}
//提取该页面的所有连接
urls := models.GetMovieUrls(sMovieHtml) //遍历url
//为了把url写入队列
//同样需要开启一个协程,这个协程专门负责从队列中取,负责get,set,
//第一判断这个url是不是一个电影,是的话加入到数据库,
// 第二是提取这个电影有关的url
//第三把url放入set(集合)里,表明这个url已经访问过
for _, url := range urls {
models.PutinUrlQueue(url)
// c.Ctx.WriteString("<br>" + url + "</br>")
}
//sUrl 需要记录到set集合里,表明这个url访问过
models.AddToSet(sUrl)
time.Sleep(time.Second) //适当休息
}
c.Ctx.WriteString("爬虫执行结束")
//models.PutinUrlQueue(sUrl)
//c.Data["Website"] = "beego.me"
//c.Data["Email"] = "astaxie@gmail.com"
//c.TplName = "index.tpl"
}

models目录下文件

package models

import (
"github.com/astaxie/beego"
"regexp" //正则包
"strings" //"strings"
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
) var (
db orm.Ormer
) type MovieInfo struct {
Id int64
Movie_id int64
Movie_name string
Movie_pic string
Movie_director string
Movie_writer string
Movie_country string
Movie_language string
Movie_main_character string
Movie_type string
Movie_on_time string
Movie_span string
Movie_grade string
Create_time string
} func init(){
orm.Debug = true //是否开启调试模式,调试模式下会打印sql语句
dbhost := beego.AppConfig.String("dbhost")
dbport := beego.AppConfig.String("dbport")
dbname := beego.AppConfig.String("dbname")
dbuser := beego.AppConfig.String("dbuser")
dbpwd := beego.AppConfig.String("dbpwd")
orm.RegisterDataBase("default", "mysql", dbuser + ":" + dbpwd + "@tcp("+dbhost + ":" + dbport + ")/" + dbname + "?charset=utf8")
orm.RegisterModel(new(MovieInfo))
db = orm.NewOrm()
} //获取电影名称
func GetMovieName(html string) string{
var movieName string
movieName = ""
if html != "" {
reg := regexp.MustCompile(`<span\s*property="v:itemreviewed">(.*?)</span>`)
result := reg.FindAllStringSubmatch(html, -)
if len(result) != {
movieName = string(result[][])
}
}
return movieName
} //获取导演
func GetMovieDirector(html string) string {
var movieDirector string
movieDirector = ""
if html != "" {
reg := regexp.MustCompile(`<a.*?rel="v:directedBy">(.*)</a>`)
result := reg.FindAllStringSubmatch(html, -)
if len( result[]) > 0 && result[0][1] != "" {
movieDirector = string(result[][])
}
}
return movieDirector
} //获取主演
func GetMovieMainCharacters(html string) string {
var movieMainCharacters string
movieMainCharacters = ""
if html != "" {
reg := regexp.MustCompile(`<a.*?rel="v:starring">(.*?)</a>`)
result := reg.FindAllStringSubmatch(html, -)
if len(result) != {
for _, v := range result {
movieMainCharacters += v[] + "/"
}
movieMainCharacters = strings.Trim(movieMainCharacters, "/")
}
}
return movieMainCharacters
} //获取电影类型
func GetMovieGenre(html string) string {
var movieGenre string
movieGenre = ""
if html != ""{
reg := regexp.MustCompile(`<span.*?property="v:genre">(.*?)</span>`)
result := reg.FindAllStringSubmatch(html, -)
if len(result) != {
for _, v := range result {
movieGenre += v[] + "/"
}
}
movieGenre = strings.Trim(movieGenre, "/")
}
return movieGenre
} //获取电影上映时间
func GetMovieOnTime(html string) string {
var movieOnTime string
movieOnTime = ""
if html != "" {
reg := regexp.MustCompile(`<span.*?property="v:initialReleaseDate".*?>(.*?)</span>`)
result := reg.FindAllStringSubmatch(html, -)
if len(result) != {
movieOnTime = string(result[][])
}
}
return movieOnTime
} //获取评分
func GetMovieGrade(html string) string {
var movieGrade string
movieGrade = ""
if html != "" {
reg := regexp.MustCompile(`<strong.*?property="v:average">(.*?)</strong>`)
result := reg.FindAllStringSubmatch(html, -) if len(result) != {
movieGrade = string(result[][])
}
}
return movieGrade
} //获取电影时长
func GetMovieRunningTime(html string) string {
var movieRunningTime string
movieRunningTime = ""
if html != "" {
reg := regexp.MustCompile(`<span.*?property="v:runtime".*?>(.*?)</span>`)
result := reg.FindAllStringSubmatch(html, -) if len(result) != {
movieRunningTime = string(result[][])
}
}
return movieRunningTime
} //入库电影
func AddMovieToDb(movie_info *MovieInfo) (int64, error) {
id, err := db.Insert(movie_info)
return id, err
} //获取当前电影页下对的所有相关电影url
func GetMovieUrls(html string) []string {
reg := regexp.MustCompile(`<a.*?href="(https://movie.douban.com/.*?)"`)
result := reg.FindAllStringSubmatch(html, -) var movieSets []string
for _, v := range result {
movieSets = append(movieSets, v[])
} return movieSets
}

redis.go文件

package models

import (
"github.com/astaxie/goredis"
)
var (
RediCclient goredis.Client
) const (
URL_QUEUE = "url_queue" //作为队列标识
URL_VISIT_SET = "url_visit_set" //记录曾经访问过的url
)
func ConnectRedis(addr string) {
RediCclient.Addr = addr
} //把提取的url放入队列
func PutinUrlQueue(url string) {
RediCclient.Lpush(URL_QUEUE, []byte(url))
} //获取队列长度
func GetQueueLength() int {
length, err := RediCclient.Llen(URL_QUEUE)
if err != nil {
return
}
return length
} //从队列里读取
func PopfromQueue() string{
res, err := RediCclient.Rpop(URL_QUEUE)
if err != nil {
panic(err)
}
return string(res)
} // 把曾经访问过的加入一个集合
func AddToSet(url string) {
RediCclient.Sadd(URL_VISIT_SET, []byte(url))
} //判断某个URL是否存在于集合中
func IsVisit(url string) bool{
isVisit, err := RediCclient.Sismember(URL_VISIT_SET, []byte(url))
if err != nil {
return false
}
return isVisit
}

Golang框架beego电影网爬虫小试牛刀的更多相关文章

  1. 使用scrapy框架做赶集网爬虫

    使用scrapy框架做赶集网爬虫 一.安装 首先scrapy的安装之前需要安装这个模块:wheel.lxml.Twisted.pywin32,最后在安装scrapy pip install wheel ...

  2. Golang框架Beego在Windows环境下小试牛刀

    Beego官网beego官网 : https://beego.me/github : https://github.com/beego Beego安装前提: ①Go 1.1+ 以确保所有功能的正常使用 ...

  3. Golang框架beego和bee的开发使用

    Golang语言简洁.明细,语法级支持协程.通道.err,非常诱惑人.平时也看了看Golang的语法,正苦于没有需求,我想把beego的源码搬过来看看. 首先,第一步:beego环境的搭建 在我之前看 ...

  4. golang的beego框架开发时出现的问题纪录

    golang的beego框架开发时出现的问题纪录1.数据库并发时问题:[ORM]2017/02/20 23:44:05 -[Queries/default] - [FAIL / db.Query / ...

  5. 放养的小爬虫--豆瓣电影入门级爬虫(mongodb使用教程~)

    放养的小爬虫--豆瓣电影入门级爬虫(mongodb使用教程~) 笔者声明:只用于学习交流,不用于其他途径.源代码已上传github.githu地址:https://github.com/Erma-Wa ...

  6. Go语言及Web框架Beego环境无脑搭建

    [原]Go语言及Web框架Beego环境无脑搭建 本文涉及软件均以截至到2013年10月12日的最新版本为准 1. 相关软件准备: 1) go1.2rc1.windows-386.msi,对应32位w ...

  7. 【收藏】收集的各种Python爬虫、暗网爬虫、豆瓣爬虫、抖音爬虫 Github1万+星

    收集的各种Python爬虫.暗网爬虫.豆瓣爬虫  Github 1万+星 磁力搜索网站2020/01/07更新 https://www.cnblogs.com/cilisousuo/p/1209954 ...

  8. 爱奇艺用券付费VIP电影+python爬虫程序+可视化界面+下载本地

    申明:本博客中的工具及源码仅供个人学习使用,请勿用作商业等其他任何违法用途!否则后果自负 直接步入正题吧! 工具开发环境:windows10,python3.6 工具界面设计:基于python 自带的 ...

  9. 【原】Go语言及Web框架Beego环境无脑搭建

    本文涉及软件均以截至到2013年10月12日的最新版本为准 1. 相关软件准备: 1) go1.2rc1.windows-386.msi,对应32位windows系统安装使用 下载地址: https: ...

随机推荐

  1. Python pickle 模块

    转自:https://www.cnblogs.com/lincappu/p/8296078.html pickle可以存储的数据类型 所有python支持的原生类型:布尔值,整数,浮点数,复数,字符串 ...

  2. 【UML】NO.48.EBook.5.UML.1.008-【UML 大战需求分析】- 组件图(Component Diagram)

    1.0.0 Summary Tittle:[UML]NO.48.EBook.1.UML.1.008-[UML 大战需求分析]- 组件图(Component Diagram) Style:DesignP ...

  3. inner join, left join, right join 和 full join

    inner join:理解为“有效连接”,两张表中都有的数据才会显示left join:理解为“有左显示”,比如on a.field=b.field,则显示a表中存在的全部数据及a.b中都有的数据,a ...

  4. CMB面试

    笔试: 1.登录验证userid password后台sql传入,有什么问题,预防措施? https://bbs.csdn.net/topics/120075716 2.cookie,session, ...

  5. mac上命令行解压rar

    时间进入到2018年12月,mac上好用的rar解压工具要收费了.被逼的没办法,用命令行吧,谁让咱擅长呢? 1,使用Homebrew安装unrar,没有自己装去 brew install unrar ...

  6. [LeetCode] 830. Positions of Large Groups_Easy tag: Two Pointers

    In a string S of lowercase letters, these letters form consecutive groups of the same character. For ...

  7. [LeetCode] 405. Convert a Number to Hexadecimal_Easy tag: Bit Manipulation

    Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two’s compl ...

  8. [LeetCode] 876. Middle of the Linked List_Easy tag: Linked List ** slow, fast pointers

    Given a non-empty, singly linked list with head node head, return a middle node of linked list. If t ...

  9. PS教程:如何批量处理图片

    1.我们先准备两个文件夹,一个用来装你要处理的图片,可以是几百上千张,另一个是空文件夹,用来装等下处理好的图片. 2.打开PS,打开未处理文件夹里的任何一张图片. 3. 在红圈中点击,新建一个动作. ...

  10. 分享一个.NET(C#)按指定字母个数截断英文字符串的方法–提供枚举选项,可保留完整单词

    分享一个.NET(C#)按字母个数截断英文字符串的方法,该方法提供枚举选项.枚举选项包括:可保留完整单词,允许最后一个单词超过最大长度限制,字符串最后跟省略号以及不采取任何操作等,具体示例实现代码如下 ...