真·从零开始使用tornado-搭建一个小说网站

tornado是什么?

官方的介绍网上有太多,在此我不再述说,附上tornado官网地址简单的说一句:tornado用来做网站的后端的,就是一般人说的服务器。

除了tornado外,python还有flask,Django等一系列的web框架可以选用

为什么选择tornado

其实这里我选择tornado,对比flask、Django我认为tornado的学习成本很低,初学者可以很快上手,从而达到加强信心,进入打怪升级的状态。另外,对比其他的框架,tornado最方便的是在部署时,只需要在前端部署一个Nginx即可上生产环境。而flask,Django等都需要部署另外的WSGI server。对于初学者来说,多一个东西要部署,就多一套东西要学习,就容易出错而不知道为什么出错,最终导致没有信心继续钻研下去。对于tornado是属于异步非阻塞框架等等技术名词,我不在这个真`从零系列做任何讲解和框架间的对比

我建议学完这个教程后,可以去学习Django。大而全的Django帮你解决了极大部分的框架问题,例如ORM等,同时丰富的社区资源,基本上可以解决你在Django上遇到的所有问题。附带一个简单讲解WSGI、uwsgi、uWSGI


让我们开始吧~

安装tornado

建议在虚拟环境中安装tornado,这样你就可以使用不同的web框架同时不会导致包管理混乱。附上地址Anaconda 配置与安装

#利用pip进行安装
pip install tornado
#安装后,通过终端输入python后
import  tornado

hello word

创建一个简单的hello word服务器

建议大家先按照我的文件目录架构创建自己的项目目录,为什么这样说呢?因为我习惯了我自己的架构,后续文章都会以我自己的项目架构为例子
文件架构

ArticleServer
|----conf
|--------config.conf 
|----method
|--------__init__.py
|----handlers
|--------__init__.py
|--------MainHandlers.py 
|----views
|----statics
|----server.py
|----application.py 
|----urlRoute.py 

server.py如下

#!/usr/bin/env python
# coding: utf-8
import tornado.ioloop
import tornado.web
import tornado.httpserver
from tornado.options import define, options
#application是我们创建的application.py
from application import application
#import sys 是为了输出和这个文件处于什么位置,若不需要输出,这个可以不import
import sys

#定义一个变量,options.port = 8887。这样的好处是,
#如果之后需要在tornado其他地方使用这个变量,
#就可以直接用options.port就可以获得了,例子下面代码有
define("port", default = 8887, help = "run on this port" ,type = int)

if __name__ == "__main__":
    tornado.options.parse_command_line()
    #根据application的设置,生成一个server
    http_server = tornado.httpserver.HTTPServer(application)
    # server调用监听方法,监听options.port(8887)端口
    http_server.listen(options.port)
    #为了打印现在server是来自哪个文件,以及在监听哪个端口
    lib = sys.path[0] + '\t' + str(options.port)
    print ('Tornado server is running at %s' %lib)
    # 使用tornado封装好的epoll接口,简单说这句必须要有xD
    tornado.ioloop.IOLoop.instance().start()

application.py如下

#!/usr/bin/env python
#-*-coding:utf-8-*-
import urlRoute
import sys
import tornado.web
import os
#urlRoute是我们创建的urlRoute.py文件
from urlRoute import url
#一些基础设定,下面讲的是,一个是html等页面模版的存放位置,
#一个是css等静态文件的存放位置
settings = {
    'template_path':os.path.join(os.path.dirname(__file__),"views"),
    'static_path':os.path.join(os.path.dirname(__file__),"static"),
}
# handlers指的是url中的内容
application = tornado.web.Application(
    handlers = url,
    **settings
)

urlRoute.py如下

#!/usr/bin/env python
#-*-coding:utf-8-*-

#找到对应的handler位置,并import
from handlers.MainHandler import MainHandler

# 存入到列表中,后续注册到server端,告诉server端不同地址,
# 应该找不同的handler,其中“/”代表的是根网站,例如:x.x.com.
# 若“/app”,则访问x.x.com/app可以访问对应的资源
url =[
    (r"/",MainHandler),
]

为什么我会把urlRoute单独写一个文件?因为当你的网站页面多了之后,你会发现有大量的网页地址需要存,单独放一个文件,便于后期维护

Mainhandler.py如下

# -*- coding: utf-8 -*-
#!/usr/bin/env python
import tornado.web

# 注意url中import的MainHandler名字,必须跟这里handler的名字一样
class MainHandler(tornado.web.RequestHandler):
    #用get的方式访问这个handler的话,就进入到get方法。
    #这里没有写post的方法,如果用post的方法进入到这个handler会报错
    def get(self):
        #write方法是打印到浏览器。若想打开一个html文件之类的,就需要用render
        self.write('hello word')

在server.py中,运行脚本


正常运行

在浏览器中输入

localhost:8887
#或者
127.0.0.1:8887
输入后展示

恭喜大家,已经写好了第一个网络服务器,是不是很简单?

如果大家不想写这么多文件,其实可以把server、handler、application、urlRoute都写到一个文件。


好了,经历过hello word的洗礼,我们来做一个小说网站吧~

小说获取

请看真·从零开始使用Requests制作简单爬虫

这篇文章没有爬下来的文件进行处理,如果通过txt文件的方式阅读是没有问题的,但通过服务端传输到浏览器中,会有问题。因为里面有javascipt以及css等向原网址请求的内容,会导致加载很慢,也有可能会打不开。所以补充了一篇,简单利用python处理文本

小说存放

因为我并没有写数据库的教程,这里也不用数据库存放的方式,使用打开对应的文件然后获取内容的方式。新建一个文件夹,取你自己喜欢的名字,但必须要以英文命名,再建不同的子文件来放不同的小说。我这里文章的名字没有使用全英,其实是不合适的。


例子

这种方式在正式的网站上,不建议用,因为文件io的读写速度很慢,会导致性能降低、并发上不去等问题,还是建议用数据库的方式

编写对应的handler(web应用)

我希望用户访问小说地址/a时,需要带上书名(name)以及章节数(num)的方式来请求。所以链接上应该是localhost:8887/a?name=zhuxian&num=1的模式
在handlers文件夹下新建一个文件,命名为ArticleHandler(其实文件名跟class名可以不一样,我习惯写成一样)

# -*- coding: utf-8 -*-
#!/usr/bin/env python
import tornado.web
import sys,os
class ArticleHandler(tornado.web.RequestHandler):
    #用get的方式访问,用post的话会报错
    def get(self):
        if 'num' and 'name' in self.request.uri:
            # 获取num和name参数,不存在则报缺少参数错误
            articleName = self.get_argument('name')
            articleNum = self.get_argument('num')

            # 把参数组装成文件地址
            filename = sys.path[0] + u'/article/%s/第%s章.txt' % (articleName,articleNum)

            #检查文件是否存在,不存在则报文件不存在错误
            if os.path.isfile(filename):
                result = ''
                # 打开对应文件,用只读的方式
                with open(filename,'r') as f:
                    # 遍历获得的文件内容,并拼接成正确的字符串输出
                    for line in f.readlines():
                        # 去除'\n'的换行符,并且替换成html的换行标签
                        line = line.strip()
                        if line and line !=' ':
                            result = result + '

' +line # 输出到网页 self.write(result) else: self.write('file does not exsit') else: self.write('missing parameter')

因为我的小说文本被我之前处理过了,所以这里需要二次处理才符合网页展示的方式,否则文字不会换行。大家按照自己的实际来修改代码

urlRoutes.py 需要增加

#!/usr/bin/env python
#-*-coding:utf-8-*-

from handlers.MainHandler import MainHandler
from handlers.ArticleHandler import ArticleHandler
url =[
    (r"/",MainHandler),
    (r"/a", ArticleHandler)
]

在server点击运行

效果图,注意导航栏的地址格式

至于如何部署到线上服务器,或者做一个内网穿透到外网等,就不在这里讲述

That's all.Thank you for your attention

你可能感兴趣的:(真·从零开始使用tornado-搭建一个小说网站)