Python处理Request请求
一、HTTP知识:
request请求方式有GET/POST/PUT/PATCH/DELETE/COPY/HEAD/OPTIONS/LINK/VIEW等
常用的request请求有:get和post 两种形式。
1.GET
用于获取资源,当采用 GET 方式请求指定资源时, 被访问的资源经服务器解析后立即返回响应内容。通常以 GET 方式请求特定资源时, 请求中不应该包含请求体,所有需要向被请求资源传递的数据都应该通过 URL 向服务器传递。
2. POST
POST 动作:用于提交数据, 当采用 POST 方式向指定位置提交数据时,数据被包含在请求体中,服务器接收到这些数据后可能会建立新的资源、也可能会更新已有的资源。同时 POST 方式的请求体可以包含非常多的数据,而且格式不限。因此 POST 方式用途较为广泛,几乎所有的提交操作都可以使用 POST 方式来完成。
3. get方式和post方式区别:
简单来说,区别是:
– GET产生 一个 TCP数据包
– POST产生 两个 TCP数据包
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
二、HTTP常见的请求参数
url:请求url地址
headers:请求头
data:发送编码为表单形式的数据
params:查询字符串
host:请求web服务器的域名地址
User-Agent:HTTP客户端运行的浏览器类型的详细信息。通过该头部信息,web服务器可以判断到当前HTTP请求的客户端浏览器类别。
Accept:指定客户端能够接收的内容类型,内容类型中的先后次序表示客户端接收的先后次序。
Accept-Encoding:指定客户端浏览器可以支持的web服务器返回内容压缩编码类型。
Accept-Language:指定HTTP客户端浏览器用来展示返回信息所优先选择的语言
Connection:表示是否需要持久连接。如果web服务器端看到这里的值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),表示连接持久有效,是不会断开的
cookie:HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。
Refer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面
具体可以参考下图:
返回结果:
三、请求示例-get请求:
1.get请求,无参数:
例如:博客园的一个url:
https://www.cnblogs.com/imyalost/ajax/news
访问时,仅需要一个url就行:就可以用:
import requests,json
res = requests.get(url='https://www.cnblogs.com/imyalost/ajax/news')
print(res.text)
2.get请求,带有参数:
例如一个系统的接口:完整的url是“https://pfgateuat.com:1199/base/dictionaries?codes=FLOW_ROLE&appCode=nba&state=enable”
则可以拆分为:基础url:“https://pfgateuat.com:1199/base/dictionaries”,再加上请求参数:“codes=FLOW_ROLE&appCode=nba&state=enable”,此时请求需要用参数:params
使用requests实现则为:
url1 = "https://pfgateuat.com:1199/base/dictionaries"
par = {'codes':'FLOW_ROLE','appCode':'nba','state':'enable'}
res1 = requests.get(url=url1,params=par)
或者直接用完成的请求url进行访问也是可以的:
url_1= "https://pfgateuat.com:1199/base/dictionaries?codes=FLOW_ROLE&appCode=nba&state=enable"
res_1 = requests.get(url=url_1)
3.get请求,带有鉴权消息,用以确认用户权限。
例如一个系统的接口,用以请求系统视图信息:"https://pfgateuat.com:1199/service-config/view/getOne/11511072"
请求信息中,headers 带有鉴权消息auth和rtoken,则完整的请求如下:
url2 = "https://pfgateuat.com:1199/service-config/view/getOne/11511072"
headers = {
'auth': 'r_Nzk2MWVycDBreGhzZGp3Yndia21eODgwNTQxNzk5MTgxOTkxNTkzMzAyNzI3',
'rtoken': 'u_NDg2MWl1aWZha2lpcWdoN2FxbWpeODgwNTQxNzk5MTMzMTU0NTkzMzAyNzI3'
}
res2 = requests.get(url=url2,headers=headers)
print(res2.json())
4.若get请求403,headers里面需要携带
python编码使用requests get获取站点内容提示403,但是使用postman获取正常,此时可以比较下postman中的请求头,会默认多一些请求参数。
加上这些必须的参数,就可以正常访问了,比如加上:'User-agent': 'Mozilla 5.10','cache-control': 'no-cache' 。访问时带上headers就可以正常获取接口返回信息。
headers = {'user-agent': 'Mozilla/5.0','cache-control': 'no-cache'}
四、请求示例-post请求:
post请求也有get请求的3种方式,另外还有其他更多的方式:
1.post请求,请求体为json格式
例如:发送消息到飞书的通知接口:"https://open.feishu.cn/open-apis/bot/v2/hook/81b413"
发送消息时,bdoy中需要对应的json请求,headers中需要标明请求类型Content-Type,请求需要用参数:data
url3 = "https://open.feishu.cn/open-apis/bot/v2/hook/81b413"
data = json.dumps({"msg_type": "text","content": {"text": "测试消息,可以替换"}})
headers = {'Content-Type': 'application/json'}
res3 = requests.post(url3,data=data,headers=headers)
print(res3.json())
2.post请求,发送body中带文件
例如:一个上传文件的接口,需要发送文件到服务端。此时请求需要用到参数:files
upload_url = "https://pfgateuat.com:1199/data-fileservice/dp/ec/save"
headers = {'P-LangId': 'en'}
with open(file_full_path, 'rb') as doc:
content = {'file': doc}
result = requests.post(upload_url, headers=headers, files=content)
print(f"the result is {result.json()}"
3. post请求,带有Authorization
常用的Authorization,鉴权类型为Basic Auth,需要输入Username,Password,
此时需要 导入包 from requests.auth import HTTPBasicAuth
请求内容中增加auth。举例:
url3 = "https://open.feishu.cn/open-apis/bot/v2/hook/81b413"
data = json.dumps({"msg_type": "text","content": {"text": "测试消息,可以替换"}})
headers = {'Content-Type': 'application/json'}
res3 = requests.post(url3,data=data,headers=headers,auth = HTTPBasicAuth(Username,Password))
print(res3.json())
五、请求示例-使用postman:
postman调通接口后,如果不清楚如果使用代码实现,可以在此工具上找到一个code按钮,点开后会看到一个产生代码的弹框
在左边选择对应语言后,就会给出对应的代码示例,特别方便。
六,消息头\消息体等字典格式存在数据库中的读取
消息头\消息体等字典格式,存在数据库中时,会用string进行存储,当若读取出来变成json格式时,直接用json.dumps()函数是无法生效的。那该如何处理呢。
介绍一种安全的方法把字符串转为字典literal_eval,使用ast.literal_eval,可以安全的把Python字典两端的引号去掉,重新转为字典
import ast
task = "{'task_name': 'own_test', 'task_type': 1, 'task_cycle': 60}"
task_dict = ast.literal_eval(task)
print(f"task type: {type(task)}, task_dict type: {type(task_dict)}")
运行结果显示:
task type: <class 'str'>, task_dict type: <class 'dict'>