Python 搭建Web站点之Web服务器与Web框架


Posted in Python onNovember 06, 2016

之前用 Django 做过一个小的站点,感觉Django太过笨重,于是就准备换一个比较轻量级的 Web 框架来玩玩。Web.py 作者已经挂掉,项目好久没有更新,所以不准备用它。而 Flask 也是一个成熟的轻量级 Web 框架,在 github 上有众多的 Star 和 Fork,文档和扩展也很丰富,值得学习。

学习一个框架最好的方式就是用框架做一个项目,在实战中理解掌握框架。这里我用 Flask 框架,使用 Mysql 数据库做了一个 论坛系统 。麻雀虽小,五脏俱全,论坛效果图如下:

Python 搭建Web站点之Web服务器与Web框架

论坛系统截图

下面是论坛的基本功能:

完整的用户模块(注册、登录,更改、找回密码、信息修改、站内消息通知); 丰富的论坛模块(创建、回复话题,站内搜索,markdown支持,@user 提醒); 强大的后台管理,支持屏蔽用户、话题、评论,支持各种条件搜索话题、评论;

本博客将会用一系列文章,记录论坛系统搭建的过程,希望对刚入门Web开发的同学有所帮助。

我们经常听说 Django, Flask 这些 python 语言的Web 框架,那么框架到底是什么,Web框架和Web服务器(Nginx, Apache等)有什么区别?离开框架还能用 Python 搭建Web站点吗?要解决这些疑问,我们有必要来理解下 Web 服务器的工作原理,以及 Web 框架的本质。

Web 服务器

当我们在浏览器输入URL后,浏览器会先请求 DNS服务器,获得请求站点的 IP 地址 。然后发送一个HTTP Request(请求)给拥有该 IP 的主机,接着就会接收到服务器给我们的 HTTP Response(响应),浏览器经过渲染后,以一种较好的效果呈现给我们。这个过程中,正是Web服务器在幕后默默做贡献。

简单来说,Web服务器是在运行在物理服务器上的一个程序,它永久地等待客户端(主要是浏览器,比如Chrome,Firefox等)发送请求。当收到请求之后,它会生成相应的响应并将其返回至客户端。Web服务器通过HTTP协议与客户端通信,因此也被称为HTTP服务器。

Python 搭建Web站点之Web服务器与Web框架

Web 服务器

Web服务器的工作原理并不复杂,一般可分成如下4个步骤:建立连接、请求过程、应答过程以及关闭连接。

建立连接:客户机通过TCP/IP协议建立到服务器的TCP连接。 请求过程:客户端向服务器发送HTTP协议请求包,请求服务器里的资源文档。 应答过程:服务器向客户机发送HTTP协议应答包,如果请求的资源包含有动态语言的内容,那么服务器会调用动态语言的解释引擎负责处理“动态内容”,并将处理得到的数据返回给客户端。由客户端解释HTML文档,在客户端屏幕上渲染图形结果。 关闭连接:客户机与服务器断开。

下面我们实现一个简单的 Web 服务器。运行示例程序后,会监听本地端口 8000,在浏览器访问 http://localhost:8000 就能看到响应内容。而我们的程序也能够打印出客户端发来的请求内容,如下图:

Python 搭建Web站点之Web服务器与Web框架

简单Web服务器

这里Request 和 Response 都需要遵守 HTTP 协议,关于 HTTP 协议的详细内容,可以读读《HTTP 权威指南》,或者看我整理的HTTP 部分内容。

虽然说web服务器的主要工作是根据request返回response,但是实际中的 Web 服务器远远比上面示例的复杂的多,因为要考虑的因素实在是太多了,比如:

缓存机制:讲一些经常被访问的页面缓存起来,提高响应速度; 安全:防止黑客的各种攻击,比如 SYN Flood 攻击; 并发处理:如何响应不同客户端同时发起的请求; 日志:记录访问日至,方便做一些分析。

目前在UNIX和LINUX平台下使用最广泛的免费 Web 服务器有Apache和 Nginx 。

Web 应用程序

Web 服务器接受 Http Request,返回 Response,很多时候 Response 并不是静态文件,因此需要有一个应用程序根据 Request 生成相应的 Response。这里的应用程序主要用来处理相关业务逻辑,读取或者更新数据库,根据不同 Request 返回相应的 Response。注意这里并不是 Web 服务器本身来做这件事,它只负责 Http 协议层面和一些诸如并发处理,安全,日志等相关的事情。

应用程序可以用各种语言编写(Java, PHP, Python, Ruby等),这个应用程序会从Web服务器接收客户端的请求,处理完成后,再返回响应给Web服务器,最后由Web服务器返回给客户端。整个架构如下:

Python 搭建Web站点之Web服务器与Web框架

Web应用程序

以 Python 为例,使用Python开发Web,最原始和直接的办法是使用CGI标准,在1998年这种方式很流行。首先确保 Web 服务器支持CGI及已经配置了CGI的处理程序,然后设置好CGI目录,在目录里面添加相应的 python 文件,每一个 python 文件处理相应输入,生成一个 html 文件即可,如下例:

# !/usr/bin/python 
# -*- coding: UTF-8 -*- 
print "Content-type:text/html" 
print # 空行,告诉服务器结束头部 
print '<html>' 
print '<head>' 
print '<meta charset="utf-8">' 
print '</head>' 
print '<body>' 
print '<h2>Hello Word! 我是一个CGI程序</h2>' 
print '</body>' 
print '</html>'

这样在浏览器访问该文件就可以得到一个简单的 Hello World 网页内容。直接通过 CGI 写 Web 应用程序看起来很简单,每一个文件处理输入,生成html。但是实际开发中,可能会遇到许多不方便的地方。比如:

每个独立的CGI脚本可能会重复写数据库连接,关闭的代码; 后端开发者会看到一堆 Content-Type 等和自己无关的 html 页面元素; Web 框架

早期开发站点确做了许多重复性劳动,后来为了减少重复,避免写出庞杂,混乱的代码,人们将 Web 开发的关键性过程提取出来,开发出了各种 Web 框架。有了框架,就可以专注于编写清晰、易维护的代码,无需关心数据库连接之类的重复性工作。

其中一种比较经典的Web框架采用了 MVC 架构,如下图所示:

Python 搭建Web站点之Web服务器与Web框架

MVC 架构

用户输入 URL,客户端发送请求,控制器(Controller)首先会拿到请求,然后用模型(Models)从数据库取出所有需要的数据,进行必要的处理,将处理后的结果发送给 视图(View),视图利用获取到的数据,进行渲染生成 Html Response返回给客户端。

以 python web 框架 flask 为例,框架本身并不限定我们用哪种架构来组织我们的应用,不过 flask 可以很好地支持以 MVC 方式组织应用。

控制器:flask 可以用装饰器来添加路由项,如下:

@app.route('/') 
def main_page(): 
  pass

模型:主要用来取出需要的数据,如下面函数中操作:

@app.route('/') 
def main_page(): 
  """Searches the database for entries, then displays them.""" 
  db = get_db() 
  cur = db.execute('select * from entries order by id desc') 
  entries = cur.fetchall() 
  return render_template('index.html', entries=entries)

视图:flask 利用 jinja2 来渲染页面,下面的模版文件指定了页面的样式:

{% for entry in entries %} 
<li> 
 <h2>{{ entry.title }}</h2> 
 <div>{{ entry.text|safe }}</div> 
</li> 
{% else %} 
<li><em>No entries yet. Add some!</em></li> 
{% endfor %}

我们知道Python有着许多的 Web 框架,而同时又有着许多的 Web 服务器(Apache, Nginx, Gunicorn等),框架和Web服务器之间需要进行通信,如果在设计时它们之间不可以相互匹配的,那么选择了一个框架就会限制对 Web 服务器的选择,这显然是不合理的。

那么,怎样确保可以在不修改Web服务器代码或网络框架代码的前提下,使用自己选择的服务器,并且匹配多个不同的网络框架呢?答案是接口,设计一套双方都遵守的接口就可以了。对python来说,就是WSGI(Web Server Gateway Interface,Web服务器网关接口)。其他编程语言也拥有类似的接口:例如Java的Servlet API和Ruby的Rack。

Python WSGI的出现,让开发者可以将 Web 框架与 Web 服务器的选择分隔开来,不再相互限制。现在,你可以真正地将不同的 Web 服务器与Web框架进行混合搭配,选择满足自己需求的组合。例如,可以使用 Gunicorn 或Nginx/uWSGI来运行Django、Flask或web.py应用。

Python 搭建Web站点之Web服务器与Web框架

WSGI 适配

下一篇我们将会仔细分析 WSGI 接口标准,然后一起来写一个简单的 WSGI Web 服务器。

Python 相关文章推荐
Python3实现的腾讯微博自动发帖小工具
Nov 11 Python
Python的print用法示例
Feb 11 Python
Python爬取APP下载链接的实现方法
Sep 30 Python
python生成tensorflow输入输出的图像格式的方法
Feb 12 Python
对python中的xlsxwriter库简单分析
May 04 Python
pytorch中tensor的合并与截取方法
Jul 26 Python
python 同时运行多个程序的实例
Jan 07 Python
python 实现12bit灰度图像映射到8bit显示的方法
Jul 08 Python
Django中使用CORS实现跨域请求过程解析
Aug 05 Python
python创建与遍历List二维列表的方法
Aug 16 Python
Python实现猜拳与猜数字游戏的方法详解
Apr 06 Python
Python FuzzyWuzzy实现模糊匹配
Apr 28 Python
读写json中文ASCII乱码问题的解决方法
Nov 05 #Python
django1.8使用表单上传文件的实现方法
Nov 04 #Python
Python+MongoDB自增键值的简单实现
Nov 04 #Python
基于Python的接口测试框架实例
Nov 04 #Python
浅谈Python爬取网页的编码处理
Nov 04 #Python
Django接受前端数据的几种方法总结
Nov 04 #Python
Python多维/嵌套字典数据无限遍历的实现
Nov 04 #Python
You might like
codeigniter框架批量插入数据
2014/01/09 PHP
php+mysqli实现批量执行插入、更新及删除数据的方法
2015/01/29 PHP
php传值和传引用的区别点总结
2019/11/19 PHP
HTML IMG标签 onload 内存溢出导致浏览器CPU占用过高
2021/03/09 Javascript
JavaScript调用Activex控件的事件的实现方法
2010/04/11 Javascript
Ext中下拉列表ComboBox组件store数据格式用法介绍
2013/07/15 Javascript
利用jQuary实现文字浮动提示效果示例代码
2013/12/26 Javascript
微信中一些常用的js方法汇总
2015/03/12 Javascript
js获取页面及个元素高度、宽度的代码
2016/04/26 Javascript
辨析JavaScript中的Undefined类型与null类型
2016/05/26 Javascript
JavaSctit 利用FileReader和滤镜上传图片预览功能
2017/09/05 Javascript
浅谈Node 调试工具入门教程
2018/03/20 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
2018/04/23 jQuery
详解在React项目中安装并使用Less(用法总结)
2019/03/18 Javascript
聊聊Vue 中 title 的动态修改问题
2019/06/11 Javascript
Vue实现日历小插件
2019/06/26 Javascript
用C++封装MySQL的API的教程
2015/05/06 Python
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
Python实现生成随机日期字符串的方法示例
2017/12/25 Python
pandas实现选取特定索引的行
2018/04/20 Python
django连接mysql配置方法总结(推荐)
2018/08/18 Python
python+opencv打开摄像头,保存视频、拍照功能的实现方法
2019/01/08 Python
python如何保存文本文件
2020/06/07 Python
法国隐形眼镜网站:VisionDirect.fr
2020/03/03 全球购物
美国购买隐形眼镜网站:Lenses For Less
2020/07/05 全球购物
如果让你测试一台高速激光打印机,你都会进行哪些测试
2012/12/04 面试题
初中地理教学反思
2014/01/11 职场文书
酒店中秋节活动方案
2014/01/31 职场文书
电子商务专业应届生求职信
2014/05/28 职场文书
投资意向书
2014/07/30 职场文书
网吧七夕活动策划方案
2014/08/31 职场文书
高中生第一学年自我鉴定2015
2014/09/28 职场文书
工程项目经理岗位职责
2015/02/02 职场文书
关于倡议书的范文
2015/04/29 职场文书
2015年社区平安建设工作总结
2015/05/13 职场文书
2016年春季运动会通讯稿
2015/11/25 职场文书