Python实现简单的Web完整版(一)

在拖了一周之后,今天终于在一个小时之内将一个迷你的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()

  

 

时间: 2024-11-03 21:25:32

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

python超简单的web服务器

今天无意google时看见,心里突然想说,python做web服务器,用不用这么简单啊,看来是我大惊小怪了. web1.py 1 2 3 #!/usr/bin/python import SimpleHTTPServer SimpleHTTPServer.test() web2.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!/usr/bin/python import SimpleHTTPServer import SocketServer

python搭建简单的web服务器

由于要做自动化和性能测试,工作中需要有一个能够控制返回消息数据的web服务器,所以用python初步实现了一个简单的web服务器,能够处理HTTP的请求(GET,POST,PUT),并完成响应.先简单说明下原理,python中实现web服务器大概分两个步骤: 1.      创建一个套接字,绑定到指定的IP和端口,保持监听 2.      创建一个handle类,当收到请求消息时,作出响应 主要使用的类有两个: HTTPServer:HTTP服务器的基类,提供了HTTP服务器的常用方法,创建服务

python 最简单的web应用(一)

对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. server.py文件 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Author: Dang Kai # @Date: 2018-08-24 14:50:02 # @Last Modified time: 2018-08-24 14:57:56 # @E-mail: 1370465454@qq.com # @Description: im

Python 最简单的web服务

python -m SimpleHTTPServer  8321   1.python 没有指定目录的参数 想启动目录 就cd到该目录下 2.在目录下创建一个index.html 3.启动web服务,(端口被占用会报错的)    

Python游戏编程外星人入侵(完整版)

准备工作:下载python,比如Anaconda3(64 bit),导入pygame游戏包 1.外星人设置,alien.py,代码: import pygame from pygame.sprite import Sprite class Alien(Sprite): """表示单个外星人的类""" def __init__(self,ai_settings,screen): """初始化外星人并设置其他位置&quo

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

代码来源https://www.shiyanlou.com/courses/552,对它进行理解,注释 #-*- coding:utf-8 -*- import BaseHTTPServer class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): '''处理请求并返回页面''' # 页面模板 Page = ''' <html> <body> <p>Hello, web!</p> </bo

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

服务器: 当客户联系时创建一个连接套接字 从这个连接接收HTTP请求(*) 解释该请求所请求的特定文件      从服务器的文件系统获取该文件 并发送文件内容 如果文件不存在,则返回"404 Not Found"(*) 客户端: 客户端可以与服务器建立TCP连接 客户端通过TCP连接请求服务器端的某一文件 在客户端显示介绍到的文件内容 注:在运行此文件前,server.py目录下需要包含file文件夹,里面装有服务器里的文件,客户端可以向服务器请求file里的文件. readme:首先

利用Python编写简单的Web静态服务器(TCP协议)

import socket def service_client(new_socket): #接受客户端的需求 request = new_socket.recv(1024) print(request) #回传数据给客户端 response = 'HTTP/1.1 200 OK\r\n' response += '\r\n' response += '<h1>你好</h1>' new_socket.send(response.encode('utf-8')) def main()

《Flask Web开发:基于Python的Web应用开发实战》pdf 完整版免费下载

<Flask Web开发:基于Python的Web应用开发实战>.pdf pdf 完整版免费下载: https://u253469.ctfile.com/fs/253469-292665036 更多电子书下载: http://hadoopall.com/book 内容简介 本书不仅适合初级Web开发人员学习阅读,更是Python程序员用来学习高级Web开发技术的优秀参考书. ? 学习Flask应用的基本结构,编写示例应用: ? 使用必备的组件,包括模板.数据库.Web表单和电子邮件支持: ?