本文为转载,原文:Golang 简单爬虫实现 · API接口开发
介绍
通过之前的实践,已经完成了小说内容定时爬取,以及小说内容的入库操作等。可是只有这些,我们还是看不了小说,因为它只在我们的数据库里。
那么今天,就简单的做几个api接口,将数据开放出来。这样只要调用api接口就能拿出数据展示了。这里面的api我就偷懒使用beego的库来实现了吧
我这边的api接口也不会太多,目前计划只做3个:
获取小说列表
获取指定小说章节列表
获取指定章节详情内容
实现
spider代码调整
由于我们的 main.go作为入口代码文件,所以,这边打算将之前的爬取数据的代码移到spider/spider.go
文件中。
改版之后的spider.go代码如下:
package spider
import (
"errors"
"github.com/Chain-Zhang/igo/ilog"
"github.com/Chain-Zhang/igo/conf"
"github.com/robfig/cron"
"ispider/models"
)
type SBook struct{
Name string
Image string
Url string
Chapters []*SChapter
}
type SChapter struct{
Title string
Url string
Order int
Pre int
Next int
Content string
}
type Spider interface{
SpiderUrl(url string) error
}
func NewSpider(from string) (Spider, error){
switch from{
case "booktxt":
return new(BookTextSpider), nil
default:
return nil, errors.New("系统暂未处理该类型的配置文件")
}
}
func Start(){
ilog.AppLog.Info("service start")
c := cron.New()
spec := conf.AppConfig.GetString("task.spec")
ilog.AppLog.Info("spec: ",spec)
c.AddFunc(spec,getBook)
c.Start()
select{}
}
func getBook(){
ilog.AppLog.Info("spider start")
books, _ := models.GetBookList("status", 1)
for _, book := range books{
go func(book *models.Book){
s, err := NewSpider(book.From)
if err != nil{
ilog.AppLog.Error("new Spider error: ", err.Error())
return
}
err = s.SpiderUrl(book.Url)
if err != nil{
ilog.AppLog.Error("new Document error: ", err.Error())
}
ilog.AppLog.Info(book.Name, "已爬取完毕")
}(book)
}
}
api文件列表
既然使用了beego的库,那么,就在原有的目录基础上先建一些相关的目录和文件吧
controllers //controllers包
----base.go //controller基类简单封装
----book.go //book的controller实现
routers //routers包
----router.go //路由分配,
main.go //入口代码文件
没错,我们的api接口实现就是这么几个文件就能搞定。
代码实现
main.go
main.go文件作为入口文件,所以这里写的并不复杂,只需要调用2个函数,以及初始化路由即可。代码如下:
package main
import (
_ "ispider/routers" //执行routers包的init函数
"ispider/spider"
"github.com/astaxie/beego"
"github.com/Chain-Zhang/igo/ilog"
)
func main() {
ilog.AppLog.Info("start")
go spider.Start() //异步执行爬虫协程
beego.Run(":8089") //开启api服务
}
controllers
base.go
base.go作为所有controllers的基类,所以需要封装一下公用的函数,提高代码复用率。
package controllers
import(
"github.com/astaxie/beego"
)
// json 返回错误码
const (
MSG_OK = 0 // 成功
MSG_ERR = -1 // 失败
)
// 基类
type BaseController struct{
beego.Controller
}
// 固定返回的json数据格式
// msgno: 错误码
// msg: 错误信息
// data: 返回数据
func (self *BaseController) toJson (msgno int, msg string, data interface{}){
out := make(map[string]interface{})
out["status"] = msgno
out["msg"] = msg
out["data"] = data
self.Data["json"] = out
self.ServeJSON()
}
从代码中可知,目前基类中只实现了一个格式化输出json的功能。
其他功能以后待扩展。
book.go
book.go就是针对小说的一个控制器了。代码如下:
package controllers
import(
"ispider/models"
)
type BookController struct{
BaseController
}
//获取小说列表
func (self *BookController) GetAll(){
books, _ := models.GetBookList()
self.toJson(MSG_OK, "成功", books)
}
// 分页获取指定小说的章节列表, 每页10条
// url参数:bookid => 小说id; page => 页码
func (self *BookController) GetChapters(){
bookid, err := self.GetInt("bookid")
if err != nil{
self.toJson(MSG_ERR, err.Error(), nil)
}
page, err := self.GetInt("page")
if err != nil{
self.toJson(MSG_ERR, err.Error(), nil)
}
chapters, _ := models.GetChapterPage(page, 10, "book_id",bookid)
self.toJson(MSG_OK, "success", chapters)
}
// 获取指定章节详细信息
// url参数: id => 章节id
func (self *BookController) GetChapter(){
id, err := self.GetInt("id")
if err != nil{
self.toJson(MSG_ERR, err.Error(), nil)
}
chapter, err := models.GetChapterById(id)
if err != nil{
self.toJson(MSG_ERR, err.Error(), nil)
}
self.toJson(MSG_OK, "success", chapter)
}
从代码中可知,这个controller也比较简单,总共实现了之前所说的三个api接口的action。具体可见代码注释。
routers
既然controllers已经完成。那么接下来就是进行路由配置了。
package routers
import(
"github.com/astaxie/beego"
"ispider/controllers"
)
func init() {
ns := beego.NewNamespace("/v1",
beego.NSNamespace("/book",
// /v1/book 获取小说列表
beego.NSRouter("/", &controllers.BookController{}, "get:GetAll"),
// /v1/book/getchapters?bookid=xxx&page=1 获取小说章节列表
beego.NSRouter("/getchapters", &controllers.BookController{}, "get:GetChapters"),
// /v1/book/chapter?id=xxx 获取章节内容
beego.NSRouter("/chapter", &controllers.BookController{}, "get:GetChapter"),
),
)
beego.AddNamespace(ns)
}
好啦,如今路由耶配合了,那么,这编码也就结束了。
运行测试
接下来就是见证奇迹的时刻了。跑起来看看吧。
控制台进入代码根目录,执行命令bee run
:
然后浏览器输入地址:http://localhost:8089/v1/book
在输入地址:http://localhost:8089/v1/book/getchapters?bookid=2&page=5
再输入章节详情的url: http://localhost:8089/v1/book/chapter?id=950
源码
完
转载请注明出处:
Golang 简单爬虫实现 · API接口开发