2021-08-27

miniweb开发
#web界面

# 1、导入模块
import socket
import threading
import framework

# 2、定义一个HTTPWebServer类
class HttpWebServer(object):
    # 3、定义__init__初始化方法
    def __init__(self):
        # 4、创建套接字对象
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置端口复用
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 5、绑定端口(前端要求必须是8000)
        tcp_server_socket.bind(('', 8000))
        # 6、设置监听
        tcp_server_socket.listen(128)
        # 7、把tcp_server_socket赋值给自身属性
        self.tcp_server_socket = tcp_server_socket


    @staticmethod
    def handle_client_request(conn_socket):
        # 10、接收客户端发送过来的数据(HTTP数据)
        client_request_data = conn_socket.recv(1024).decode('utf-8')
        if len(client_request_data) > 0:
            print(client_request_data)
            # 获取Ajax发送过来的所有HTTP请求数据
            request_data = client_request_data.split('\r\n')
            # print(request_data)
            # pop()方法,主要功能,弹出列表中的最后一个元素,但是如果给定一个索引,其就只弹出指定索引的那个元素
            request_line = request_data.pop(0)
            request_line_data = request_line.split(' ')  # ['GET','/index','HTTP/1.1']

            # print(request_data)
            # 11、把请求头信息,都放入字典中{'Host':'127.0.0.1:8000'}
            request_header = {}
            # ['Host: 127.0.0.1:8000', '']
            for header in request_data:
                if header == '':
                    continue
                # request_header[key] = value
                request_header[header.split(": ")[0]] = header.split(": ")[1]

            # 12、获取请求资源路径
            request_path = request_line_data[1]
            # print(request_path)

            # 13、获取用户请求的参数,如/detail?id=100
            request_query = request_path.split('?')
            if len(request_query) > 1:
                request_path = request_query[0]  # /detail
                query_str = request_query[1]  # id=100
            else:
                query_str = None

            # 14、把获取的请求路径、请求参数以及请求头组装成字典格式
            requests = {
                'path': request_path,
                'query_str': query_str,
                'header': request_header
            }

            # 15、编写符合wsgi协议的数据包(等待发送给Web应用程序 => 爱读书实际代码)
            env = {
                'request_path': request_path,
                'requests': requests
            }
            # env = {
            #   'request_path': '/index或/detail',
            #   'requests': {
            #       'path': '/index或/detail',
            #       'query_str': 'id=100',
            #       'header': {'Host':'127.0.0.1:8000', 'User-Agent':'Chrome/92'}
            #   }
            # }

            # 16、响应数据给浏览器客户端
            response_line = 'HTTP/1.1 200 OK\r\n'
            # 响应头
            response_header = 'Server:pwb\r\nAccess-Control-Allow-Credentials:true\r\nAccess-Control-Allow-Origin:*\r\nAccess-Control-Allow-Methods:GET, POST, PUT\r\nAccess-Control-Allow-Headers:X-Custom-Header\r\n'
            # 响应体(关键:到底应该返回什么内容给前端 => JSON格式的数据包)
            response_body = framework.handle_request(env)
            # 响应数据
            response_data = (response_line + response_header + '\r\n' + response_body).encode('utf-8')

            # 16、返回数据给客户端
            conn_socket.send(response_data)

            # 17、关闭客户端连接
            conn_socket.close()

    def start(self):
        while True:
            # 8、接收客户端连接请求
            conn_socket,ip_port = self.tcp_server_socket.accept()
            # 9、创建子线程
            sub_thread = threading.Thread(target=self.handle_client_request, args=(conn_socket, ))
            sub_thread.setDaemon(True)
            sub_thread.start()

if __name__ == '__main__':
    web_server = HttpWebServer()  # 得到套接字对象
    web_server.start()  # 开始工作,准备接收客户端请求(HTTP)



#framework界面    

# 导入pymysql模块
import pymysql
import json
import logging

def index(env):
    # 创建连接
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='root', database='book', charset='utf8')
    # 获取游标
    cursor = conn.cursor()
    # 执行SQL语句
    sql = "select * from bookinfo;"
    cursor.execute(sql)
    # print(cursor.fetchall()) => ((), (), ()) => [{}, {}, {}] => json.dumps => json_str
    stock_data = cursor.fetchall()
    center_data_list = []
    for data in stock_data:
        center_data_list.append({
            "id": data[0],
            "name": data[1],
            "auth": data[2],
            "img_url": data[3],
            "rank": data[4]
        })
    # 把以上得到的图书信息转换为JSON格式的字符串
    json_str = json.dumps(center_data_list, ensure_ascii=False)

    # 关闭游标与连接
    cursor.close()
    conn.close()

    # 返回数据给web.py
    return json_str

def detail(env):
    # 返回客户端请求的图书id编号(如id=100)
    query_str = env['requests']['query_str']
    # 创建连接
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='root', database='book', charset='utf8')
    # 获取游标
    cursor = conn.cursor()
    # 执行SQL语句
    sql = "select * from bookinfo where %s;" % query_str
    cursor.execute(sql)
    row = cursor.fetchone()

    data_dict = {
        "id": row[0],
        "name": row[1],
        "auth": row[2],
        "img_url": row[3],
        "read": row[5],
        "comment": row[6],
        "score": row[8],
        "content": row[7],
        "synopsis": row[9]
    }

    # json.dumps只能转换列表和字典
    json_str = json.dumps(data_dict, ensure_ascii=False)

    # 把图书的阅读量进行+1操作
    sql = "update bookinfo set bread=bread+1 where %s" % query_str
    cursor.execute(sql)
    conn.commit()

    # 进行数据埋点
    logging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
                        stream=open('log.txt', 'a', encoding='utf-8'))
    logging.info({
        # 记录用户行为
        'bookClick': {
            # 获取用户设备信息
            "identification": env['requests']['header']['User-Agent'].split(' ')[-2],
            # 获取客户端IP
            # 获取用户跳转路径
            "entrance": env['requests']['header']['Referer'],
            # 获取图书名称与阅读量
            "bookname": data_dict['name'],
            "read": data_dict["read"]
        }
    })

    # 关闭游标与连接
    cursor.close()
    conn.close()

    # 返回JSON格式数据给客户端浏览器
    return json_str


# 定义路由列表(Django框架)
route_list = [
    ('/index', index),
    ('/detail', detail)
]

def handle_request(env):
    request_path = env['request_path']
    # request_path = '/detail'
    for path,func in route_list:
        if request_path == path:
            return func(env)
    else:
        return '404 Not Found' 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值