用Python进行Web开发 您所在的位置:网站首页 python跟web 用Python进行Web开发

用Python进行Web开发

#用Python进行Web开发| 来源: 网络整理| 查看: 265

1 Web 开发介绍2 HTTP协议简介2.1 HTTP请求流程2.2 HTTP格式 3 HTML简介3.1 HTML简介3.2 CSS简介3.3 JavaScript简介 4 WSGI接口4.1 WSGI接口4.2 运行WSGI服务 5 Web框架——Flask6 使用模板

1 Web 开发介绍

最早的软件都是运行在大型机上的,软件使用者通过“哑终端”登陆到大型机上去运行软件。后来随着PC机的兴起,软件开始主要运行在桌面上,而数据库这样的软件运行在服务器端,这种Client/Server模式简称CS架构。

随着互联网的兴起,人们发现,CS架构不适合Web,最大的原因是Web应用程序的修改和升级非常迅速,而CS架构需要每个客户端逐个升级桌面App,因此,Browser/Server模式开始流行,简称BS架构。

在BS架构下,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web页面,并把Web页面展示给用户即可。

当然,Web页面也具有极强的交互性。由于Web页面是用HTML编写的,而HTML具备超强的表现力,并且,服务器端升级后,客户端无需任何部署就可以使用到新的版本,因此,BS架构迅速流行起来。

Web应用开发可以说是目前软件开发中最重要的部分。Web开发也经历了好几个阶段:

静态Web页面:由文本编辑器直接编辑并生成静态的HTML页面,如果要修改Web页面的内容,就需要再次编辑HTML源文件,早期的互联网Web页面就是静态的;CGI:由于静态Web页面无法与用户交互,比如用户填写了一个注册表单,静态Web页面就无法处理。要处理用户发送的动态数据,出现了Common Gateway Interface,简称CGI,用C/C++编写。ASP/JSP/PHP:由于Web应用特点是修改频繁,用C/C++这样的低级语言非常不适合Web开发,而脚本语言由于开发效率高,与HTML结合紧密,因此,迅速取代了CGI模式。ASP是微软推出的用VBScript脚本编程的Web开发技术,而JSP用Java来编写脚本,PHP本身则是开源的脚本语言。MVC:为了解决直接用脚本语言嵌入HTML导致的可维护性差的问题,Web应用也引入了Model-View-Controller的模式,来简化Web开发。ASP发展为ASP.Net,JSP和PHP也有一大堆MVC框架。

Python的诞生历史比Web还要早,由于Python是一种解释型的脚本语言,开发效率高,所以非常适合用来做Web开发。Python有上百种Web开发框架,有很多成熟的模板技术,选择Python开发Web应用,不但开发效率高,而且运行速度快。

2 HTTP协议简介

在Web应用中,服务器把网页传给浏览器,实际上就是把网页的HTML代码发送给浏览器,让浏览器显示出来。而浏览器和服务器之间的传输协议是HTTP,所以:

HTML是一种用来定义网页的文本;HTTP是在网络上传输HTML的协议,用于浏览器和服务器的通信。 2.1 HTTP请求流程 步骤1:浏览器首先向服务器发送HTTP请求,请求包括: 方法:GET还是POST,GET仅请求资源,POST会附带用户数据; 路径:/full/url/path; 域名:由Host头指定:Host: www.sina.com.cn 以及其他相关的Header; 如果是POST,那么请求还包括一个Body,包含用户数据。步骤2:服务器向浏览器返回HTTP响应,响应包括: 响应代码:200表示成功,3xx表示重定向,4xx表示客户端发送的请求有错误,5xx表示服务器端处理时发生了错误; 响应类型:由Content-Type指定,例如:Content-Type: text/html;charset=utf-8表示响应类型是HTML文本,并且编码是UTF-8,Content-Type: image/jpeg表示响应类型是JPEG格式的图片; 以及其他相关的Header; 通常服务器的HTTP响应会携带内容,也就是有一个Body,包含响应的内容,网页的HTML源码就在Body中。步骤3:如果浏览器还需要继续向服务器请求其他资源,比如图片,就再次发出HTTP请求,重复步骤1、2。

Web采用的HTTP协议采用了非常简单的请求-响应模式,从而大大简化了开发。当我们编写一个页面时,我们只需要在HTTP响应中把HTML发送出去,不需要考虑如何附带图片、视频等,浏览器如果需要请求图片和视频,它会发送另一个HTTP请求,因此,一个HTTP请求只处理一个资源。

HTTP协议同时具备极强的扩展性,虽然浏览器请求的是http://www.sina.com.cn/的首页,但是新浪在HTML中可以链入其他服务器的资源,比如,从而将请求压力分散到各个服务器上,并且,一个站点可以链接到其他站点,无数个站点互相链接起来,就形成了World Wide Web,简称"WWW"。

2.2 HTTP格式

每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。

HTTP协议是一种文本协议,所以,它的格式也非常简单。HTTP GET请求的格式:

GET /path HTTP/1.1 Header1: Value1 Header2: Value2 Header3: Value3

每个Header一行一个,换行符是\r\n。

HTTP POST请求的格式:

POST /path HTTP/1.1 Header1: Value1 Header2: Value2 Header3: Value3 body data goes here...

当遇到连续两个\r\n时,Header部分结束,后面的数据全部是Body。

HTTP响应的格式:

200 OK Header1: Value1 Header2: Value2 Header3: Value3 body data goes here...

HTTP响应如果包含body,也是通过\r\n\r\n来分隔的。请再次注意,Body的数据类型由Content-Type头来确定,如果是网页,Body就是文本,如果是图片,Body就是图片的二进制数据。

当存在Content-Encoding时,Body数据是被压缩的,最常见的压缩方式是gzip,所以,看到Content-Encoding: gzip时,需要将Body数据先解压缩,才能得到真正的数据。压缩的目的在于减少Body的大小,加快网络传输。

3 HTML简介 3.1 HTML简介

最简单的HTML:

Hello Hello, world!

可以用文本编辑器编写HTML,然后保存为hello.html,双击或者把文件拖到浏览器中,就可以看到效果。

HTML文档就是一系列的Tag组成,最外层的Tag是。规范的HTML也包含...和...(注意不要和HTTP的Header、Body搞混了),由于HTML是富文档模型,所以,还有一系列的Tag用来表示链接、图片、表格、表单等等。

3.2 CSS简介

CSS是Cascading Style Sheets(层叠样式表)的简称,CSS用来控制HTML里的所有元素如何展现,比如,给标题元素加一个样式,变成48号字体,灰色,带阴影:

Hello h1 { color: #333333; font-size: 48px; text-shadow: 3px 3px 3px #666666; } Hello, world! 3.3 JavaScript简介

JavaScript虽然名称有个Java,但它和Java真的一点关系没有。JavaScript是为了让HTML具有交互性而作为脚本语言添加的,JavaScript既可以内嵌到HTML中,也可以从外部链接到HTML中。如果希望当用户点击标题时把标题变成红色,就必须通过JavaScript来实现:

Hello h1 { color: #333333; font-size: 48px; text-shadow: 3px 3px 3px #666666; } function change() { document.getElementsByTagName('h1')[0].style.color = '#ff0000'; } Hello, world! 4 WSGI接口 4.1 WSGI接口

Web应用的本质就是:

浏览器发送一个HTTP请求;服务器收到请求,生成一个HTML文档;服务器把HTML文档作为HTTP响应的Body发送给浏览器;浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。

所以,最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。Apache、Nginx、Lighttpd等这些常见的静态服务器就是干这件事情的。

如果要动态生成HTML,就需要把上述步骤自己来实现。若自己来写这些底层代码,时间成本太高。正确的做法是底层代码由专门的服务器软件实现,用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。

这个接口就是WSGI:Web Server Gateway Interface。

WSGI接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求。一个最简单的Web版本的“Hello, web!”:

def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'Hello, web!']

上面的application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

environ:一个包含所有HTTP请求信息的dict对象;start_response:一个发送HTTP响应的函数。

在application()函数中,调用:

start_response('200 OK', [('Content-Type', 'text/html')])

就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每个Header用一个包含两个str的tuple表示。

通常情况下,都应该把Content-Type头发送给浏览器。其他很多常用的HTTP Header也应该发送。

然后,函数的返回值b'Hello, web!'将作为HTTP响应的Body发送给浏览器。

有了WSGI,我们关心的就是如何从environ这个dict对象拿到HTTP请求信息,然后构造HTML,通过start_response()发送Header,最后返回Body。

application()函数必须由WSGI服务器来调用,因为如果自己调用,两个参数environ和start_response没法提供,返回的bytes也没法发给浏览器。有很多符合WSGI规范的服务器,我们可以挑选一个来用。

Python内置了一个WSGI服务器,这个模块叫wsgiref,它是用纯Python编写的WSGI服务器的参考实现。所谓“参考实现”是指该实现完全符合WSGI标准,但是不考虑任何运行效率,仅供开发和测试使用。

4.2 运行WSGI服务

先编写hello.py,实现Web应用程序的WSGI处理函数:

# hello.py def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [b'Hello, web!']

然后,再编写一个server.py,负责启动WSGI服务器,加载application()函数:

# server.py # 从wsgiref模块导入: from wsgiref.simple_server import make_server # 导入我们自己编写的application函数: from hello import application # 创建一个服务器,IP地址为空,端口是8000,处理函数是application: httpd = make_server('', 8000, application) print('Serving HTTP on port 8000...') # 开始监听HTTP请求: httpd.serve_forever()

确保以上两个文件在同一个目录下,然后在命令行输入python server.py来启动WSGI服务器。 注意:如果8000端口已被其他程序占用,启动将失败,请修改成其他端口。 启动成功后,打开浏览器,输入http://localhost:8000/,就可以看到结果了。

5 Web框架——Flask

在处理很多个不同的URL时,代码不好维护。WSGI提供的接口虽然比HTTP接口高级了不少,但和Web App的处理逻辑比,还是比较低级,我们需要在WSGI接口之上能进一步抽象,让我们专注于用一个函数处理一个URL,至于URL到函数的映射,就交给Web框架来做。

由于用Python开发一个Web框架十分容易,所以Python有上百个开源的Web框架。在此选择一个比较流行的Web框架——Flask来使用。若想进行详细学习,可参考:用Python进行Web开发——Flask框架入门学习

用Flask编写Web App比WSGI接口简单,先安装Flask。 然后写一个app.py,处理3个URL,分别是:

GET /:首页,返回Home;GET /signin:登录页,显示登录表单;POST /signin:处理登录表单,显示登录结果。

Flask通过Python的装饰器在内部自动地把URL和函数给关联起来,写出来的代码就像这样:

from flask import Flask from flask import request app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def home(): return 'Home' @app.route('/signin', methods=['GET']) def signin_form(): return '''

Sign In

''' @app.route('/signin', methods=['POST']) def signin(): # 需要从request对象读取表单内容: if request.form['username']=='admin' and request.form['password']=='password': return 'Hello, admin!' return 'Bad username or password.' if __name__ == '__main__': app.run()

运行python app.py,Flask自带的Server在端口5000上监听:

$ python app.py * Running on http://127.0.0.1:5000/

除了Flask,常见的Python Web框架还有:

Django:全能型Web框架;web.py:一个小巧的Web框架;Bottle:和Flask类似的Web框架;Tornado:Facebook的开源异步Web框架。 6 使用模板

Web App不仅仅是处理逻辑,展示给用户的页面也非常重要。由于在Python代码里拼字符串是不现实的,所以,模板技术出现了。

使用模板,需要预先准备一个HTML文档,这个HTML文档不是普通的HTML,而是嵌入了一些变量和指令,然后,根据传入的数据,替换后,得到最终的HTML,发送给用户: 在这里插入图片描述 这就是传说中的MVC:Model-View-Controller,中文名“模型-视图-控制器”。

Python处理URL的函数就是C:Controller,Controller负责业务逻辑,比如检查用户名是否存在,取出用户信息等等;包含变量{{ name }}的模板就是V:View,View负责显示逻辑,通过简单地替换一些变量,View最终输出的就是用户看到的HTML。Model是用来传给View的,这样View在替换变量的时候,就可以从Model中取出相应的数据。 上面的例子中,Model就是一个dict:{ 'name': 'Michael' }。只是因为Python支持关键字参数,很多Web框架允许传入关键字参数,然后,在框架内部组装出一个dict作为Model。

把上次直接输出字符串作为HTML的例子用MVC模式改写一下:

from flask import Flask, request, render_template app = Flask(__name__) @app.route('/', methods=['GET', 'POST']) def home(): return render_template('home.html') # 实现模板的渲染 @app.route('/signin', methods=['GET']) def signin_form(): return render_template('form.html') # 实现模板的渲染 @app.route('/signin', methods=['POST']) def signin(): username = request.form['username'] password = request.form['password'] if username=='admin' and password=='password': return render_template('signin-ok.html', username=username) return render_template('form.html', message='Bad username or password', username=username) if __name__ == '__main__': app.run()

Flask默认支持的模板是jinja2,所以先直接安装jinja2: 编写jinja2模板:

home.html 用来显示首页的模板:

Home Home

form.html 用来显示登录表单的模板:

Please Sign In {% if message %} {{ message }} {% endif %} Please sign in:


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有