6.7. requests 模块说明
Author: Onceday Date: 2022年12月10日
6.7.1. 模块基本情况
基于 webclient.c 开发,暂时支持最简单的 get 请求和 post 请求。
在 get 请求上额外支持简单的拼接 URL。
能够指定额外的请求头关键字。
返回数据包括状态码,负载内容长度,和负载内容。
6.7.2. 安装
requestment.txt 加入
requests
6.7.3. 使用方法
首先导入模块
import requests
然后输入方法和 url 地址
result = requests.request("GET", "http://pikascript.com/")
如果一切成功,result 中将含有以下信息
content_length: int 返回文本内容的长度 text: str 返回的文本内容 state_code: int get请求的状态码 headers: str 返回的响应头 url: str get请求的url地址
其中,text是最核心的返回数据。
对于(2)中的请求,可以如下展示:
print(result.text)
这就是网页
http://pikascript.com/
的内容了。如果这个
request
失败,那么 result 会是一个空对象,因此需要判断 result 是否为空。
request
模块目前可用参数有如下几种:
request(method: str, url: str, params=None, headers=None, data=None) -> Response:
method
, 可选GET
、POST
,最基本的两种操作url
, 即标准的 url 字段,注意有长度限制,最好不要超过 2Kb。params
,可选,用于在已给的 url 字段后面拼接参数,会自动转义字符,也可以在 url 中手动拼接。headers
,可选,用于指定请求头的关键字,如Host
等,用于满足自定义的需求,正常使用无需填写。data
,用于在POST
中传输的负载数据,注意是字符串类型。Response
,返回的响应对象,只有发送的请求响应成功,才会返回,否则为None
。
6.7.4. 拼接 URL
get 方法额外支持的就是拼接 URL,这个过程也会涉及一些字符的转换。因为 URL 里面有一些特殊字符是不能直接展示的,必须转义才行。
使用很简单,如下:
result = requests.request("GET", "http://pikascript.com/package", params = {"name":"get-test", "id":"23"})
其中,url会拼接成如下:
http://pikascript.com/package?name=get-test&id=23
然后便以此来发送 http
请求,这里并没有做很复杂的操作,只是简单的把字典里面的参数连接起来。
然后如下来显示返回的数据,只有成功收到响应 result 才不为空,所以要判断一下:
if result not None:
print(result.status_code)
print(result.content_length)
print(result.text)
6.7.5. post 接口
该接口比较原始,如果想自己上传数据,则需要手动拼接内容。原因如下:
http 协议非常复杂,没有必要重复实现一遍。
嵌入式的需求是固定的。
下面是一个典型的使用:
import requests
print("test")
form_data = '------WebKitFormBoundaryrEPACvZYkAbE4bYB\r\nContent-Disposition: form-data; name="file"; filename="test_file.txt"\r\nContent-Type: text/plain\r\n\r\nhello, pikascript!\r\n------WebKitFormBoundaryrEPACvZYkAbE4bYB\r\nContent-Disposition: form-data; name="id"\r\n\r\n1670666272201\r\n------WebKitFormBoundaryrEPACvZYkAbE4bYB\r\nContent-Disposition: form-data; name="uploadFileNum"\r\n\r\n1\r\n------WebKitFormBoundaryrEPACvZYkAbE4bYB--\r\n'
print(form_data)
header = {"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryrEPACvZYkAbE4bYB"}
a = requests.request("POST", "http://pikascript.com/upload", headers=header, data=form_data)
if a not None:
print(a.headers)
print(a.content_length)
print(a.text)
正常输出如下:
HTTP/1.1 200 OK
309
{"files":{"file":[{"fieldName":"file","originalFilename":"test_file.txt","path":"html/upload/pJwNgC8fobWOLN_l9qmAk-Oi.txt","headers":{"content-disposition":"form-data; name=\"file\"; filename=\"test_file.txt\"","content-type":"text/plain"},"size":18}]},"fields":{"id":["1670666272201"],"uploadFileNum":["1"]}}
下面来解释一下上面的行为:
首先指定额外的请求头关键字,
Content-Type
表明负载的类型,multipart/form-data
是一种常见的表单类型,boundary
指定表单不同部分之间的分割线。Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrEPACvZYkAbE4bYB
----WebKitFormBoundaryrEPACvZYkAbE4bYB
就是用来分割负载内容的,这只是单纯的一些随机字符,所以可以参杂一些标识WebKitFormBoundaryr
在里面。你会发现,这个分隔符可能和传输的内容重复!对的,可能重复,重复就会导致服务器解析失败,然后需要再传一次。因此每次都是随机的字符串,连续多次重复的概率是非常低的。
上面表单数据即编码后的字符串,其含有三种数据:
文件名、文件类型和文件的内容”hello, pikascript!”。
对应ID。
上传文件的数目。
POST 关键需要以下两个请求关键字:
header buffer:POST http://pikascript.com/upload HTTP/1.1 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrEPACvZYkAbE4bYB Content-Length: 408
对于一个post来说,其请求头最简单时只需要如上内容即可。
返回码可以看到为 200,这表示 post 请求成功了,当然,这个 post 响应还携带一些关于上传内容的信息。
最直接的 post 传输,只需要如下调用即可。
a = requests.request("POST", "http://pikascript.com/upload", data=binary_data)
这个传输的是二进制数据,即默认填充以下内容:
Content-Type: application/octet-stream
Content-Length: (sizeof(data))
但这需要服务器对应支持解析,很明显,http://pikascript.com/upload
不能解析这种数据。
6.7.6. 运行过程
整个 request 代码是基于 webclient 开发,并进行了简单的更改。
当运行如下语句时,实际进行了下列过程:
result = requests.request("GET", "http://pikascript.com/package", params = {"name":"get-test"}, headers = {"Connection":"keep-alive"})
首先创建一个 session 对象,申请 4Kb buffer 空间存放请求头。
写入
GET
到 buffer 中。写入 “http://pikascript.com/package” 到 buffer 中,
写入 url 的拼接部分
params = {"name":"get-test"}
到 buffer 中,然后补充必要的其他字符。写入指定的关键字
headers = {"Connection":"keep-alive"}
到 buffer 中。对于 POST,会额外写入
Content-Type
和Content-Length
内容。这里会开始解析 URL 地址,比如将域名解析为实际的 IP 地址。
写入默认的标准头部分关键字,包括
Host: (自行解析)
User-Agent: PikaScript HTTP Agent
Accept: */*
创建 socket 连接,开始通信。
先发送请求头部分数据,再发送数据(对于 POST )。
然后是等待接收数据了,这个时候有超时的可能。
解析数据,写入 content_length、text、header、status_code 这四个内容。
最后可通过返回的 result 对象查看上面四个数据。