侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

使用Python的Tornado框架实现一个Web端图书展示页面

Python  /  管理员 发布于 7年前   232

首先,为什么选择Tornado:
1.高性能的网络库,这可以和gevent,twisted,libevent等做对。
提供了异步io支持,超时事件处理,在此基础上提供了tcpserver,httpclient,尤其是curlhttpclient,
在现有http客户端中肯定排第一。可以用来做爬虫,游戏服务器,据我所知业界已有使用tornado作为游戏服务器

2.web框架,这可以和django,flask对。
提供了路由,模板等web框架必备组件。与其他区别是tornado是异步的,天然适合长轮训,
这也是friendfeed发明tornado的原因,当前flask也可以支持,但必须借助gevent等

3.较为完备的http服务器,这点可以和nginx,apache对比,
但只支持http1.0,所以使用nginx做前段不仅是为了更好利用多核,也是让其支持http1.1

4.完备的wsgi服务器,这可以和gunicore,gevent wsgi server做对比,
也就是说可以让flask运行在tornado之上,让tornado加速flask

5.提供了完备的websocket支持,这让html5的游戏等提供了便利。
像知乎长轮训就是使用了websocket,但websocket手机支持的不是很好,
前段时间不得不使用定时ajax发送大量请求,期待手机浏览器赶快奋起直追

使用tornado创建一个简单的图书介绍页
好了,言归正传,下面我们来看一下这个图书介绍页的代码实现:
1.创建一个web服务的入口文件 blockmain.py

#coding:utf-8import tornado.webimport tornado.httpserverimport tornado.ioloopimport tornado.optionsimport os.pathimport jsonimport urllib2from tornado.options import define, optionsdefine("port", default=8000, help="run on the given port", type=int)class MainHandler(tornado.web.RequestHandler):  def get(self):    self.render(      "index.html",      page_title = "Burt's Books ¦ Home",      header_text = "Welcome to Burt's Books!",      books = ['细说php','python','PHP','小时代']    )class HelloModule(tornado.web.UIModule):  def render(self):    return'<h1>I am yyx and this is an information from module hello!</h1>'class BookModule(tornado.web.UIModule):  def render(self,bookname):    doubanapi = r'https://api.douban.com/v2/book/'    searchapi = r'https://api.douban.com/v2/book/search?q='    searchurl = searchapi+bookname    searchresult = urllib2.urlopen(searchurl).read()    bookid = json.loads(searchresult)['books'][0]['id']    bookurl = doubanapi+bookid    injson = urllib2.urlopen(bookurl).read()    bookinfo = json.loads(injson)    return self.render_string('modules/book.html',book = bookinfo)  def embedded_javascript(self):    return "document.write(\"hi!\")"  def embedded_css(self):    return '''.book {background-color:#F5F5F5}         .book_body{color:red}    '''  def html_body(self):    return '<script>document.write("Hello!")</script>'if __name__ == "__main__":  tornado.options.parse_command_line()  app = tornado.web.Application(    handlers = [      (r'/',MainHandler),    ],    template_path = os.path.join(os.path.dirname(__file__),'templates'),    static_path = os.path.join(os.path.dirname(__file__),'static'),    debug = True,    ui_modules={'Hello':HelloModule,'Book':BookModule}    )  http_server = tornado.httpserver.HTTPServer(app)  http_server.listen(options.port)  tornado.ioloop.IOLoop.instance().start()

说明一下,一些基本的MVC概念:
tornado也是通过pathinfo模式来匹配用户的输入来获得参数,然后再调用相应的处理函数,它是通过为各种匹配模式设定相应的class类来处理,比如我这里就是通过class MainHandler来处理来自/的get请求
MainHandler把请求render渲染到index.html,参数在index.html中通过{{参数}}来调用

2.建立相应的模板,先创建一个基础的父类main.html模板,创建templates目录,在它下面创建main.html,这个模板只是定义了最基础的网页框架,里面的具体内容由继承于它的子类来具体实现

<html><head>  <title>{{ page_title }}</title>  <link rel="stylesheet" href="https:/article/{{ static_url("css/style.css") }}" /></head><body>  <div id="container">    <header>      {% block header %}<h1>Burt's Books</h1>{% end %}    </header>    <div id="main">      <div id="content">        {% block body %}{% end %}      </div>    </div>    <footer>      {% set mailLink = '<a href="https:/article/mailto:[email protected]">Contact Us</a>' %}      {% set script = '<script>alert("hello")</script>' %}      {% block footer %}        <p>          For more information about our selection, hours or events, please email us at{% raw mailLink %}          <!-- {% raw script %} 这里将原样输出,也就是会弹一个框-->         </p>      {% end %}    </footer>  </div>  <script src="https:/article/{{ static_url("js/script.js") }}"></script>  </body></html>

这里是定义了一个主框架,其中里面的{% block header %}<h1>Burt's Books</h1>{% end %}是为了子类模板的继承的块(block),当子类继承了这个main.html,具体这个块里写什么内容由子类来实现,不实现的话就使用父类的默认 值,如是这里的<h1>Burt's Books</h1>,MainHandler类是render到一个index.html,那么接下来写一个index.html来继承这 个父类

{% extends "main.html" %}{% block header %}  <h1>{{ header_text }}</h1>{% end %}{% block body %}  <div id="hello">    <p>Welcome to Burt's Books!</p>    {% module Hello() %}    {% for book in books %}      {% module Book(book) %}    {% end %}    <p>...</p>  </div>{% end %}

简单简洁吧,这也是使用了继承的好处,不用再重复写父类的东西,只要实现父类的block内容即可
MainHandler类里的render方法中的参数

page_title = "Burt's Books | Home",header_text = "Welcome to Burt's Books!",books = ['细说php','python','PHP','小时代']

将会通过参数传送到这里来
tornado的模板里可以使用python的代码,加上{% %}当使用if for while等要使用{% end %}结尾
代码中{% module Book(book) %} 将会调用入口服务文件中的定义和'Book'所对应的模块
ui_modules={'Hello':HelloModule,'Book':BookModule} 也就是BookModule,查看上面的BookModule定义

class BookModule(tornado.web.UIModule):  def render(self,bookname):    doubanapi = r'https://api.douban.com/v2/book/'    searchapi = r'https://api.douban.com/v2/book/search?q='    searchurl = searchapi+bookname    searchresult = urllib2.urlopen(searchurl).read()    bookid = json.loads(searchresult)['books'][0]['id']    bookurl = doubanapi+bookid    injson = urllib2.urlopen(bookurl).read()    bookinfo = json.loads(injson)    return self.render_string('modules/book.html',book = bookinfo)

BookModule 继承自tornado.web.UIModule,UI模块的使用是最后render_string()方法来把一个对象渲染到一个模板中去,我这里简单 的使用了豆瓣的图书api,先通过search来查询一下包含关键词的图书信息,返回第一条图书的id,再使用book api来查询该图书的具体信息,将这个具体图书的信息render到对应的模板
在templates 目录下创建modules目录,再下创建一个book.html,这里是具体的book要显示的内容框架

<div class="book">  <h3 class="book_title">{{ book["title"] }}</h3>  <a href="https:/article/{{book['alt']}}" target="_blank"><p>点击查看详情</p></a>  {% if book["subtitle"] != "" %}    <h4 class="book_subtitle">{{ book["subtitle"] }}</h4>  {% end %}  <img src="https:/article/{{ book["images"]["large"] }}" class="book_image"/>  <div class="book_details">    <div class="book_date_released">Released: {{ book["pubdate"]}}</div>        <h5>Description:</h5>    <div class="book_body">{% raw book["summary"] %}</div>  </div></div>

最后的文件目录结构应该是这样的

├── blockmain.py└── templates  ├── index.html  ├── main.html  └── modules    └── book.html

程序的执行是这样的:
先通过路径‘/'来使用MainHandler类访问index.html---->index.html继承自 main.html---->index.html中的{% module Book(book) %}反过来查找blockmain.py中的Book对应的ui_modules---->ui_modules中将查询得到的book对象内容渲 染到modules下的book.html中,这样就把完整的内容呈现出来了,没有做前端…… 通过python blockmain.py启动服务,通过http://localhost:8000 来访问得到如下的网页

您可能感兴趣的文章:

  • python利用JMeter测试Tornado的多线程
  • python tornado修改log输出方式
  • python tornado使用流生成图片的例子
  • python-tornado的接口用swagger进行包装的实例
  • 关于Python核心框架tornado的异步协程的2种方法详解
  • python tornado微信开发入门代码
  • Tornado Web Server框架编写简易Python服务器
  • python使用tornado实现登录和登出
  • python使用tornado实现简单爬虫
  • Python tornado队列示例-一个并发web爬虫代码分享
  • Tornado协程在python2.7如何返回值(实现方法)
  • python用装饰器自动注册Tornado路由详解
  • 深入解析Python的Tornado框架中内置的模板引擎
  • 为Python的Tornado框架配置使用Jinja2模板引擎的方法
  • Python的Tornado框架实现异步非阻塞访问数据库的示例
  • Python的Tornado框架实现图片上传及图片大小修改功能
  • Python的Tornado框架的异步任务与AsyncHTTPClient
  • Python对Tornado请求与响应的数据处理


  • 上一条:
    深入解析Python的Tornado框架中内置的模板引擎
    下一条:
    Python的requests网络编程包使用教程
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客