PythonWeb开发基础(三)类Flask框架请求封装

news2025/1/16 0:59:49

课程地址:Python 工程师进阶技术图谱

文章目录

  • 类Flask框架请求封装
    • HTTP请求解析的python实现
      • 1、解析查询字符串
      • 2、多值问题
    • 使用webob库解析请求
    • Bug记录
      • bug:AttributeError: module 'cgi' has no attribute 'parse_qs'


类Flask框架请求封装

Web服务器

  • 本质是个TCP服务器,监听在特定端口上
  • 支持HTTP协议,能够将HTTP请求报文进行解析,能够把响应数据进行HTTP协议的报文封装并返回浏览器端。

APP程序内部也可以请求其它Server,此时就是代理作用。总之,app里面就可以实现各种复杂的功能,只要最后满足WSGI的要求就行。

上一节中实现的app,不论收到什么反馈,都产生一样的响应,这一节将尝试对请求进行解析

HTTP请求解析的python实现

1、解析查询字符串

查询字符串

  • ?name=tom&id=1000,不同的参数之间使用&分隔开。

代码

from wsgiref.simple_server import make_server

def simple_app(environ:dict, start_response):
    # 读取“请求方法”和“查询字符串”,并提前查询字符串中的信息
    method = environ.get('REQUEST_METHOD')
    print(method)
    query_string = environ.get('QUERY_STRING')
    print(query_string)
    # 解析查询字符串
    d = {}
    for item in query_string.split('&'):
        k,_,v = item.partition('=')
        d[k] = v
    print(d)

    status = '200 OK'
    headers = [('Content-type', 'text/plain; charset=utf-8')]

    start_response(status, headers)

    ret = [query_string.encode('utf-8')]

    return ret  # 报文的正文部分,即网页内容

with make_server('0.0.0.0', 9000, simple_app) as httpd:
    print("Serving on port 9000...")
    try:
        httpd.serve_forever()
    except Exception as e:
        print(e)
    except KeyboardInterrupt:
        print('stop')
        httpd.server_close()

然后使用我Edge的Postwoman工具发起一个GET请求,url为http://127.0.0.1:9000/?name=tom&id=1000

程序在python端就输出解析的查询字符串(第三行),我们将它解析成了一个字典

'''
GET
name=tom&id=1000&age=20
{'name': 'tom', 'id': '1000'}
'''

对于解析查询字符串的一段代码也可以使用下面两种写法,更加简单(行数更少,但感觉可读性不太好):

d = {k:v for k, _, v in map(lambda x:x.partition('='), query_string.split('&'))}
d = {k:v for k, _, v in [item.partition('=') for item in query_string.split('&')]}

或者使用库:

from urllib.parse import parse_qs
qs = parse_qs(query_string)

改用库后,再次发起请求,python端输出解析后的字典:

'''
{'name': ['tom'], 'id': ['1000']}
'''

2、多值问题

此时字典中的value值变成了一个列表,这是因为在url中可以对一个参数传入多值,例如将我们请求的url改成http://127.0.0.1:9000/?name=tom&id=1000&id=666,python端的输出将变成:

{'name': ['tom'], 'id': ['1000', '666']}

使用webob库解析请求

前面,我们获取请求的信息还需要记下信息的名称

method = environ.get('REQUEST_METHOD')

这显然十分麻烦。而使用webob库,我们可以通过对象的属性来访问请求的信息,只需将environ参数传给webob库中的Request对象,就可以自动实现解析。代码如下:

from wsgiref.simple_server import make_server
from webob import Request


def simple_app(environ:dict, start_response):
    request = Request(environ)

    query_string = request.query_string
    methon = request.method
    print('methon, query_string: ', methon, query_string)
    print('request: ', request.GET) # 来自查询字符串的参数
    print('type(request.GET): ', type(request.GET)) # dict
    print('request.POST: ', request.POST) # 来自POST的参数
    print('request.params: ', request.params) # 所有的参数,包含url的查询字符串,和POST的正文
    print('request.path: ', request.path)
    print('request.headers: ', request.headers) # 请求头

    status = '200 OK'
    headers = [('Content-type', 'text/plain; charset=utf-8')]

    start_response(status, headers)

    ret = [query_string.encode('utf-8')]
    return ret  # 报文的正文部分,即网页内容

with make_server('0.0.0.0', 9000, simple_app) as httpd:
    print("Serving on port 9000...")
    try:
        httpd.serve_forever()
    except Exception as e:
        print(e)
    except KeyboardInterrupt:
        print('stop')
        httpd.server_close()

我使用Postwoman测试工具发送了一个POST请求,它url的查询字符串中有参数,POST也传输了一个参数age

在这里插入图片描述

下面是python端的输出

'''
Serving on port 9000...
methon, query_string:  POST name=tom&id=1000&id=666
request:  GET([('name', 'tom'), ('id', '1000'), ('id', '666')])
type(request.GET):  <class 'webob.multidict.GetDict'>
request.POST:  MultiDict([('age', '20')])
request.params:  NestedMultiDict([('name', 'tom'), ('id', '1000'), ('id', '666'), ('age', '20')])
request.path:  /
request.headers:  <webob.headers.EnvironHeaders object at 0x000002A24D1D1F00>
'''

Bug记录

bug:AttributeError: module ‘cgi’ has no attribute ‘parse_qs’

错误代码如下

from cgi import parse_qs
qs = parse_qs(query_string)

点进cgi的库查找parse_qs,发现了下面这段代码:

if sys.version_info < (3, 8):
    def parse_qs(qs: str, keep_blank_values: bool = ..., strict_parsing: bool = ...) -> dict[str, list[str]]: ...
    def parse_qsl(qs: str, keep_blank_values: bool = ..., strict_parsing: bool = ...) -> list[tuple[str, str]]: ...

if sys.version_info >= (3, 7):
    def parse_multipart(
        fp: IO[Any], pdict: SupportsGetItem[str, bytes], encoding: str = ..., errors: str = ..., separator: str = ...
    ) -> dict[str, list[Any]]: ...

显然,当 s y s . v e r s i o n _ i n f o > = ( 3 , 8 ) sys.version\_info >= (3, 8) sys.version_info>=(3,8)的时候,函数parse_qs是不会被定义的。应该是python版本的问题,我换成python3.7版本时,就可以正常运行了。

其实,cgi库已经过期了,使用urllib库就好。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/273612.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++提高编程】list 容器详解(附测试用例与结果图)

目录1. list容器1.1 list基本概念1.2 list构造函数&#xff08;初始化&#xff09;1.3 list 赋值和交换1.4 list 大小操作1.5 list 插入和删除1.6 list 数据存取1.7 list 反转&#xff08;reverse&#xff09;、排序&#xff08;sort&#xff09;和去重&#xff08;unique&…

电脑技巧:电脑状态监控神器TrafficMonitor介绍

有的时候我们为了解决某些电脑问题&#xff0c;需要监控电脑的实时网速、CPU、内存等的占用情况。一般情况下我们可以打开电脑任务管理器&#xff0c;就可以实时监控硬件状态&#xff0c;但如果查看频率较高的话&#xff0c;需要每次进入任务管理器就显得比较麻烦。今天小编分享…

【漏洞修复】 CVE Linux 系统应用漏洞修复笔记

这里写自定义目录标题说明SSL/TLS协议信息泄露漏洞(CVE-2016-2183)漏洞信息解决办法验证方法修复步骤说明查询当前使用的openssl版本号下载并安装新版本的openssl替换nginx中使用的openssl到最新版说明 此文章主要记录工作中遇到的漏洞以及修复过程。 SSL/TLS协议信息泄露漏洞…

【LeetCode】员工的重要性 | 图像渲染 | 岛屿问题

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《阿亮爱刷题》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;员工的重…

力扣SQL刷题4

目录1158. 市场分析 I1280. 学生们参加各科测试的次数1174. 即时食物配送 II585. 2016年的投资1158. 市场分析 I 题型&#xff1a;表1和表2连接时&#xff0c;如何把没有对应数据输出来。即表1中所有id列对应的表2数据输出&#xff0c;没用的输出0 解答1&#xff1a;left join…

【Linux】权限

&#x1f525;&#x1f525; 欢迎来到小林的博客&#xff01;&#xff01;       &#x1f6f0;️博客主页&#xff1a;✈️小林爱敲代码       &#x1f6f0;️博客专栏&#xff1a;Linux之路       &#x1f6f0;️社区&#xff1a; 进步学堂       …

关于软考的一些前期准备

国家软考的中级职称证书&#xff0c;含金量较高且没有报考资质限制 报名时间和考试时间具体请看官网&#xff1a;中国计算机技术职业资格网 不同的资格证书时间和要求不一样&#xff0c;注意查看 上半年&#xff1a; 下半年&#xff1a; 下半年&#xff1a; 软件评测师考试说…

Spring Boot 中事半功倍的一些工具类

系列文章地址&#xff1a;https://blog.csdn.net/perfect2011/article/details/124603278在日常开发中经常有这样那样的小功能需要实现&#xff0c;这些一般会作为工具类存在&#xff0c;在项目中有一些通用的功能&#xff0c;Spring内置了需要工具类&#xff0c;而且经过了大量…

京东一面:20种异步,你知道几种? 含协程

背景说明&#xff1a; 异步&#xff0c;作为性能调优核心方式之一&#xff0c;经常被用于各种高并发场景。 很多场景多会使用到异步&#xff0c;比如&#xff1a; 场景1&#xff1a; 超高并发 批量 写 mysql 、批量写 elasticSearch 场景2&#xff1a; 超高并发 批量 IO 场景…

30分钟掌握 Hive SQL 优化(解决数据倾斜)

Hive SQL 几乎是每一位互联网分析师的必备技能&#xff0c;相信每一位面试过大厂的童鞋都有被面试官问到 Hive 优化问题的经历。所以掌握扎实的 HQL 基础尤为重要&#xff0c;既能帮分析师在日常工作中“如鱼得水”提高效率&#xff0c;也能在跳槽时获得一份更好的工作 offer。…

【23种设计模式】设计模式介绍与分类

前言 本文为 【23种设计模式】设计模式介绍与分类 相关知识介绍&#xff0c;下边将对什么是设计模式&#xff0c;设计模式的分类与23种设计模式的关键点进行详尽介绍~ &#x1f4cc;博主主页&#xff1a;小新要变强 的主页 &#x1f449;Java全栈学习路线可参考&#xff1a;【…

蓝桥算法两周训练营--Day2:DP

T1&#xff1a;P1048 [NOIP2005 普及组] 采药 - 洛谷 代码&#xff1a; 1、二维Dp&#xff1a; package 蓝桥算法两周训练营__普及组.Day2_dp;import java.util.Scanner;/*** author yx* date 2023-02-05 13:16*/ public class t1 {// P1048 [NOIP2005 普及组] 采药 - 洛…

java春招大厂面试,差点让面试官给我聊挂喽!

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01; 八股文整的挺好&#xff0c;算法也刷的够多&#xff0c;但问到项目就很拉胯。 这可能是现在大部分没有实际项目经验的校招生和一直从事边角料开…

环境变量【Linux】

文章目录&#xff1a;Linux环境变量介绍常用的环境变量如何查看环境变量命令搜索路径PATH与环境变量相关的命令环境变量的组织方式通过代码的方式获取环境变量通过系统调用获取或设置环境变量环境变量的全局属性&#xff08;继承&#xff09;Linux环境变量介绍 环境变量&#…

【王道数据结构】第五章(下) | 树 | 二叉树

目录 一、树的存储结构 1、双亲表示法(顺序存储)&#xff1a; 2、孩子表示法(顺序链式) 3、孩子兄弟表示法(链式存储&#xff09; 二、树、森林的遍历 1、树的先根遍历 2、树的后根遍历 3、层序遍历&#xff08;队列实现&#xff09; 4、森林的遍历 三、二叉排序树 …

电子技术——IC偏置-电流源、电流镜、电流舵

电子技术——IC偏置-电流源、电流镜、电流舵 IC偏置设计基于恒流源技术。在IC中的一个特定的区域&#xff0c;会生成一个精确的DC电流&#xff0c;这称为 参考电流 &#xff0c;之后通过电流镜复制到各个所需支路&#xff0c;并且通过电流舵进行电流转向。这项技术为IC的多级放…

知识图谱实战(01):从0-1搭建图片服务器

作者&#xff1a;艾文编程职业&#xff1a;程序员&#xff0c;BAT大厂资深工程师摘要&#xff1a;搜索/推荐场景下给用户展示大量的图片信息&#xff0c;那么这些数据是通过专门的图片服务器来访问的。 我们在基于知识图谱的智能搜索系统中&#xff0c;对搜索出来的每条记录都有…

支付系统核心架构设计思路(万能通用)

文章目录1. 支付系统总览核心系统交互业务图谱2. 核心系统解析交易核心交易核心基础交易类型抽象多表聚合 & 订单关联支付核心支付核心总览支付行为编排异常处理渠道网关资金核算3. 服务治理平台统一上下文数据一致性治理CAS校验幂等 & 异常补偿对账准实时对账DB拆分异…

fpga图像处理(sobel算子)

【声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 关于sobel算子,前面已经讲过计算方法了。一种是上下的sobel算子,一种是左右的sobel算子,两者都相当于prewitt算子的进一步拓展。当然,之前的实现方法都是基于python和opencv实现…

【Leetcode】面试题 16.05. 阶乘尾数、HJ7 取近似值

作者&#xff1a;小卢 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 面试题 16.05. 阶乘尾数 HJ7 取近似值 面试题 16.05. 阶乘尾数 面试题 16.05. 阶乘尾数 …