需求:
使用urllib代替requests发送请求。这个需求的上级需求:为了减少pyinstaller打包后的文件大小以及加载速度。
替代过程:
1. 先用urllib代替requests的get请求,无压力,不写
2. 用urllib代替requests的post请求,曲折迂回,极其繁琐,大概写下。
大概替换过程
一、替换前代码
1.1 client 端:
requests代码:
import requests
import josn
data={'pay_amonut': '45'}
try:
res = json.loads(requests.post(url='localhost:10000/get_barcode', data=data, timeout=(15, 15)).text)
except Exception as e:
print(e)
1.2 server端代码
flask代码:
from flask import Flask, request, Blueprint
app_blue = Blueprint('get_code', __name__)
@app_blue.route('/get_barcode',methods=["POST"])
def get_tasks():
pay_amount=request.form['pay_amount']
return {'pay_amount': pay_amount}
server_app = Flask(__name__)
server_app.register_blueprint(app_blue)
if __name__ == '__main__':
server_app.run(host='localhost', port=10000)
以上代码可以正常运行,postman也可以正常返回测试结果。
二、曲折的替换开始
2.1 第一次替换
2.1.1 替换client代码
urllib代码:
from urllib import request, urlopen, parse
data = {'pay_amonut': '45'}
try:
req = request.Request(url='localhost:10000', method='post', data=data)
res = json.loads(request.urlopen(req).read())
except Exception as e:
prtin(e)
2.1.2 server代码不变
flask代码:
from flask import Flask, request, Blueprint
app_blue = Blueprint('get_code', __name__)
@app_blue.route('/get_barcode',methods=["POST"])
def get_tasks():
pay_amount=request.form.get('pay_amount')
return {'pay_amount': pay_amount}
server_app = Flask(__name__)
server_app.register_blueprint(app_blue)
if __name__ == '__main__':
server_app.run(host='localhost', port=10000)
测试结果:
client端(with UI): 默默退出,不报错!
server端(with UI): 没有收到get_barcode的请求

2.2 第二次替换
2.2.1 替换client代码
urllib代码:
from urllib import request, urlopen, parse
data = {'pay_amonut': '45'}
data = parse.urlencode(data)
try:
req = request.Request(url='localhost:10000', method='post', data=data)
res = json.loads(request.urlopen(req).read())
except Exception as e:
prtin(e)
2.2.2 server端代码未变
测试结果:
client端(with UI): 默默退出,不报错!
server端(with UI): 依然没有收到get_barcode的请求

2.3 第三次替换
2.3.1 client端:
urllib代码:
from urllib import request, urlopen, parse
data = {'pay_amonut': '45'}
data = parse.urlencode(data)
try:
req = request.Request(url='localhost:10000', method='post', data=data.encode())
res = json.loads(request.urlopen(req).read())
except Exception as e:
prtin(e)
2.3.2 server端
flask代码:
from flask import Flask, request, Blueprint
app_blue = Blueprint('get_code', __name__)
@app_blue.route('/get_barcode',methods=["POST"])
def get_tasks():
# 至于为什么会输出这么多,因为这是个简洁版的过程,实际过程,我试了在headers里添加各种content_type
print(request.headers)
print(request.values)
print(request.get_data())
print(request.get_json())
print(request.form)
print(request.args)
print(request.data)
pay_amount=request.values.get('pay_amount')
return {'pay_amount': pay_amount}
server_app = Flask(__name__)
server_app.register_blueprint(app_blue)
if __name__ == '__main__':
server_app.run(host='localhost', port=10000)
测试结果:
**客户端:(with UI):**终于不再默默退出,出现了期待已久的二维码…

server端:

结论:
- 在使用urllib发送post请求时:(1) 必须先进行urlencode(); (2) 使用urllib.request.Request构造请求体时,一定要传入data,并且需要对urlencode之后的data进行encode()编码。(题外话有其他解释。)
- 在flask里边尽量使用request.values.get():原因:(1) values包含了args和form的数据,便于兼容get和post方式的代码。(2) 使用get方法时,如果请求的参数/数据中没有,会得到None,而不会报错。
题外话:
- 在本次折腾中,再次学习了headers中的’Content-Type’的一些取值。
- 客户端发送json格式的数据,在flask怎么获取(这个能怎么用,以后再研究,估计是用在前后端restful开发中)。``
测试结果:
postman代替client:

server端(print的顺序和上面的一样):

urllib关键代码:
headers = {'Content-Type': 'application/json'}
data = {'pay_amount': '45'}
req = request.Request(url='localhost:10000', method='post', data=json.dumps(data).encode('utf-8'))
res = json.loads(request.urlopen(req).read())
server端(print的顺序和上面的一样)::


本文详细记录了使用Urllib库替换Requests库发送POST请求的过程,包括遇到的问题及解决方法,适用于减少PyInstaller打包文件大小的需求场景。
760

被折叠的 条评论
为什么被折叠?



