在拖了一周之后,今天终于在一个小时之内将一个迷你的Web写出来了,最近改其它项目的bug头好大,但是好喜欢这样的状态。

黑色的12月,所有的任务都聚集在了12月,然后期末考试也顾不上好好复习了,但是但是,我要一步步的把手上的项目做出来!!!

回归正题了:这次的Python网络编程也是速成的,对于Python只是看了大体的语言框架后就直接上手写网络编程部分了,有错希望前辈指正~~

Python版本:2.7

IDE:PyCharm

接着前面几篇基础的这次主要修改了下面的部分:

最终完成的是下面的结构:

一、响应静态页面

所以这一步就该处理静态页面了,处理静态页面就是根据请求的页面名得到磁
盘上的页面文件并返回。
在当前目录下创建新文件 plain.html,这是测试用的静态页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Plain Page</title>
</head>
<body>
<p>HAha, this is plain page...</p>
</body>
</html>

  在 server.py 中导入需要的库

import sys, os, BaseHTTPServer
为服务器程序写一个异常类

class ServerException(Exception):
''' 服务器内部错误 '''
pass  重写  do_GET 函数
# deal with a request
def do_GET(self):
try:
full_path = os.getcwd() + self.path if not os.path.exists(full_path):
raise ServerException("'{0}' not found".format(self.path))
elif os.path.isfile(full_path):
self.handle_file(full_path)
# 访问根路径
elif os.path.isdir(full_path):
# fullPath = os.path.join(fullPath, "index.html")
full_path += "index.html"
if os.path.isfile(full_path):
self.handle_file(full_path)
else:
raise ServerException("'{0}' not found".format(self.path))
else:
raise ServerException("Unknown object '{0}'".format(self.path))
except Exception as msg:
self.handle_error(msg)

首先看完整路径的代码, os.getcwd() 是当前的工作目录, self.path 保存了请求的相对路径, RequestHandler 是继承自 BaseHTTPRequestHandler 的,它已经

将请求的相对路径保存在 self.path 中了。
编写文件处理函数和错误处理函数:

# page model
Page = '''
<html>
<body>
<table border=2s>
<tr> <td>Header</td> <td>Value</td> </tr>
<tr> <td>Date</td><td> and time</td> <td>{date_time}</td> </tr>
<tr> <td>Client host</td> <td>{client_host}</td> </tr>
<tr> <td>Client port</td> <td>{client_port}</td> </tr>
<tr> <td>Command</td> <td>{command}</td> </tr>
<tr> <td>Path</td> <td>{path}</td> </tr>
</table>
</body>
</html>
'''
Error_Page = """\
<html>
<body>
<h1>Error accessing {path}</h1>
<p>{msg}</p>
</body>
</html>
""" def handle_error(self, msg):
content = self.Error_Page.format(path=self.path, msg=msg)
self.send_content(content, 404) def handle_file(self, full_path):
# 处理 python 脚本
if full_path.endswith('.py'):
# data 为脚本运行后的返回值
data = subprocess.check_output(['python', full_path])
self.send_content(data)
return
try:
with open(full_path, 'rb') as reader:
content = reader.read()
self.send_content(content)
except IOError as msg:
msg = "'{0}' cannot be read: {1}".format(self.path, msg)
self.handle_error(msg) 看下效果喽:

再测试一下错误的路径:

上面也是返回了错误页面

但同时如果用 postman 观察的话,返回的是200 状态码,要不要希望它能够返回 404呢,哈哈,所以还需要修改一

下 handle_error 与 send_content 函数

这次的话如果在输入不存在的 url 就能返回 404 状态码了。

在根 url 显示首页内容

在工作目录下添加 index.html 文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h1>Index Page </h1>
<p>I love Python, to be honest</p> </body>
</html>

  此时do_GET函数也要修改下:

    def do_GET(self):
try:
full_path = os.getcwd() + self.path if not os.path.exists(full_path):
raise ServerException("'{0}' not found".format(self.path))
elif os.path.isfile(full_path):
self.handle_file(full_path)
# 访问根路径
elif os.path.isdir(full_path):
# fullPath = os.path.join(fullPath, "index.html")
full_path += "index.html"
if os.path.isfile(full_path):
self.handle_file(full_path)
else:
raise ServerException("'{0}' not found".format(self.path))
else:
raise ServerException("Unknown object '{0}'".format(self.path))
except Exception as msg:
self.handle_error(msg)
看看效果了:

.CGI 协议

有时候呢,大部分人是不希望每次都给服务器加新功能时都要到服务器的源代码里进行
修改。所以,如果程序能独立在另一个脚本文件里运行那就再好不过啦。下面实现CGI:

如下面在 html 页面上显示当地时间。
创建新文件 time.py

from datetime import datetime

print '''\
<html>
<body>
<p>Generated {0}</p>
</body>
</html>'''.format(datetime.now())

  导入 import subprocess,这是一个在程序中生成子进程的模块,它是对fork(),exec()等函数做了封装

【不过目前我还没有掌握,学长说以后会在操作系统课程中学到~~~】

修改 handleFile()函数

    def handle_file(self, full_path):
# 处理 python 脚本
if full_path.endswith('.py'):
# data 为脚本运行后的返回值
data = subprocess.check_output(['python', full_path])
self.send_content(data)
return
try:
with open(full_path, 'rb') as reader:
content = reader.read()
self.send_content(content)
except IOError as msg:
msg = "'{0}' cannot be read: {1}".format(self.path, msg)
self.handle_error(msg)
看看效果了:

 

w(゚Д゚)w。

它成功的显示了现在的时间,看到后不禁要担心过会儿一定不能再被教学区的阿姨赶出自习室了。。

不不,又没有去跑步啊。。。

上面的功能都是在学长写的文档的指导下做了自己的修改一行一行实现的~~

下篇还会在此基础上对BaseHTTPServer.HTTPServer,

BaseHTTPServer.BaseHTTPRequestHandler 再学习去实现, 现在只是实现了最基
础的部分。

后面完整的代码如下:

# -*-coding:utf-8 -*-
import BaseHTTPServer
import os
import subprocess class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"""dealt with and return page"""
# page model
Page = '''
<html>
<body>
<table border=2s>
<tr> <td>Header</td> <td>Value</td> </tr>
<tr> <td>Date</td><td> and time</td> <td>{date_time}</td> </tr>
<tr> <td>Client host</td> <td>{client_host}</td> </tr>
<tr> <td>Client port</td> <td>{client_port}</td> </tr>
<tr> <td>Command</td> <td>{command}</td> </tr>
<tr> <td>Path</td> <td>{path}</td> </tr>
</table>
</body>
</html>
'''
Error_Page = """\
<html>
<body>
<h1>Error accessing {path}</h1>
<p>{msg}</p>
</body>
</html>
""" def handle_error(self, msg):
content = self.Error_Page.format(path=self.path, msg=msg)
self.send_content(content, 404) def handle_file(self, full_path):
# 处理 python 脚本
if full_path.endswith('.py'):
# data 为脚本运行后的返回值
data = subprocess.check_output(['python', full_path])
self.send_content(data)
return
try:
with open(full_path, 'rb') as reader:
content = reader.read()
self.send_content(content)
except IOError as msg:
msg = "'{0}' cannot be read: {1}".format(self.path, msg)
self.handle_error(msg) # deal with a request
def do_GET(self):
try:
full_path = os.getcwd() + self.path if not os.path.exists(full_path):
raise ServerException("'{0}' not found".format(self.path))
elif os.path.isfile(full_path):
self.handle_file(full_path)
# 访问根路径
elif os.path.isdir(full_path):
# fullPath = os.path.join(fullPath, "index.html")
full_path += "index.html"
if os.path.isfile(full_path):
self.handle_file(full_path)
else:
raise ServerException("'{0}' not found".format(self.path))
else:
raise ServerException("Unknown object '{0}'".format(self.path))
except Exception as msg:
self.handle_error(msg) @property
def create_page(self):
values = {
'date_time': self.date_time_string(),
'client_host': self.client_address[0],
'client_port': self.client_address[1],
'command': self.command,
'path': self.path
}
page = self.Page.format(**values)
return page
pass def send_content(self, content, status=200):
self.send_response(status) self.send_header("Content-type", "text/html")
self.send_header("Content-Length", str(len(content)))
self.end_headers()
self.wfile.write(content)
pass class ServerException(Exception):
pass
if __name__ == '__main__':
server_address = ('127.0.0.1', 5555)
server = BaseHTTPServer.HTTPServer(server_address, RequestHandler)
server.serve_forever()

  

 

Python实现简单的Web完整版(一)的更多相关文章

  1. Python 实现简单的 Web

    简单的学了下Python, 然后用Python实现简单的Web. 因为正在学习计算机网络,所以通过编程来加强自己对于Http协议和Web服务器的理解,也理解下如何实现Web服务请求.响应.错误处理以及 ...

  2. python超简单的web服务器

    今天无意google时看见,心里突然想说,python做web服务器,用不用这么简单啊,看来是我大惊小怪了. web1.py   1 2 3 #!/usr/bin/python import Simp ...

  3. python 最简单的web应用(一)

    对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. server.py文件 #!/usr/bin/env python # -*- coding: ...

  4. Python分布式爬虫打造搜索引擎完整版-基于Scrapy、Redis、elasticsearch和django打造一个完整的搜索引擎网站

    Python分布式爬虫打造搜索引擎 基于Scrapy.Redis.elasticsearch和django打造一个完整的搜索引擎网站 https://github.com/mtianyan/Artic ...

  5. 国内某Python大神自创完整版,系统性学习Python

    很多小伙伴纠结于这个一百天的时间,我觉得完全没有必要,也违背了我最初放这个大纲上来的初衷,我是觉得这个学习大纲还不错,自学按照这个来也能相对系统的学习知识,而不是零散细碎的知识最后无法整合,每个人的基 ...

  6. Python实现简单的Web(续)

    写的有点乱..希望大神指教~~Python的缩进可真的将我缠了好久,想起我们班大神说缩进也是代码啊..修改之前的代码来显示请求的信息,同时重新整理一下代码: class RequestHandler( ...

  7. Python实现简单的Web服务器 解析

    代码来源https://www.shiyanlou.com/courses/552,对它进行理解,注释 #-*- coding:utf-8 -*- import BaseHTTPServer clas ...

  8. python一个简单的web服务器和客户端

    服务器:      当客户联系时创建一个连接套接字      从这个连接接收HTTP请求(*)      解释该请求所请求的特定文件      从服务器的文件系统获取该文件      并发送文件内容 ...

  9. 笨办法学python - 专业程序员的养成完整版PDF免费下载_百度云盘

    笨办法学python - 专业程序员的养成完整版PDF免费下载_百度云盘 提取码:xaln  怎样阅读本书 由于本书结构独特,你必须在学习时遵守几条规则 录入所有代码,禁止复制粘贴 一字不差地录入代码 ...

随机推荐

  1. BZOJ 2006: [NOI2010]超级钢琴

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2613  Solved: 1297[Submit][Statu ...

  2. angular服务一

    angular服务 [$apply()] jquery内数据绑定 要用$apply(),不然不能在js内通过angular绑定数据 <!DOCTYPE html> <html lan ...

  3. maven: 基本使用

    1.项目管理工具:Maven的repository,说白了就是dependency的仓库,它按照一定的规则将dependency存放起来,以作缓存,如果本机的 repository找不到某个depen ...

  4. JavaScript进阶之DOM

    文档对象模型DOM 文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.我们最 ...

  5. Python学习笔记(1)

    001 #通过bat命令运行pyhon py文件,并将结果输出到txt文件.# D:\ResearchContent\Exercise_Programm\Start\Start.py>C:\Us ...

  6. AngularJs ng-repeat限制循环次数

    重复数组:<ul ng-init='name=[1,2,3,3]'> <li ng-repeat="name in name track by $index"&g ...

  7. C#技术漫谈之垃圾回收机制(GC)

    GC的前世与今生 虽然本文是以.NET作为目标来讲述GC,但是GC的概念并非才诞生不久.早在1958年,由鼎鼎大名的图林奖得主John McCarthy所实现的Lisp语言就已经提供了GC的功能,这是 ...

  8. node-glob学习

    node的glob模块允许你使用 *等符号, 来写一个glob规则,像在shell里一样,获取匹配对应规则的文件. 这个glob工具基于javascript.它使用了 minimatch 库来进行匹配 ...

  9. 聊一聊PV和并发

    最近和几个朋友,聊到并发和服务器的压力问题.很多朋友,不知道该怎么去计算并发?部署多少台服务器才合适? 所以,今天就来聊一聊PV和并发,还有计算web服务器的数量 的等方法.这些都是自己的想法加上一些 ...

  10. 《你不常用的c#之XX》

    你不常用的c#之一>:略谈unsafe http://blog.csdn.net/robingaoxb/article/details/6199508 <你不常用的c#之二>:略谈G ...