• Requests库POST请求


    前言

    POST请求用于向服务器提交数据,比如增删改数据,提交一个表单新建一个用户、或修改一个用户等。
    对于POST请求,我们可以通过浏览器开发者工具或者其他外部工具来进行抓包,得到请求的URL、请求头(request headers)以及请求的表单data信息,这三样恰恰是我们用Requests模拟POST请求时需要的。
    关于请求头的配置和GET请求是一样的,都是定义headers属性即可。
    而关于POST请求提交的参数,是和GET请求是不一样的。
    post请求四种传送正文方式:

    • (1)请求正文是application/x-www-form-urlencoded
    • (2)请求正文是multipart/form-data
    • (3)请求正文是raw
    • (4)请求正文是binary

    这四种提交数据的方式,是在请求头Content-Type属性中来定义。

    1、application/x-www-form-urlencoded

    Reqeusts支持以application/x-www-form-urlencoded数据格式发送POST请求(标准的POST请求数据格式,默认),只需要将请求的参数构造成一个字典,然后传给requests.post()的data参数即可。
    示例:

    1. """
    2. 1.学习目标
    3. 必须掌握requests库发送post请求方法
    4. 2.HTTP协议中post请求参数类型
    5. requests.post(url, data=None, json=None, **kwargs)
    6. 根据不同的请求参数类型分为如下几种:
    7. x-www-form-data-urlencoded
    8. raw_json格式
    9. form-data
    10. binary
    11. 3.json格式
    12. # 1.导入requests库
    13. # 2.明确请求地址
    14. # 3.明确请求参数
    15. data = {key:value} 字典格式
    16. # 4.发送请求
    17. requests.post(url=url,json=data)
    18. 4.需求
    19. 通过访问http://httpbin.org/post接口,验证post参数类型
    20. """
    21. # 1.导入requests库
    22. import requests
    23. import json
    24. # 2.明确请求地址
    25. url = "http://httpbin.org/post"
    26. # 3.明确请求参数
    27. data = {
    28. "dep_id": "T01",
    29. "dep_name": "Test学院",
    30. "master_name": "Test-Master",
    31. "slogan": "Here is Slogan"
    32. }
    33. # 4.发送请求
    34. response = requests.post(url=url, data=data)
    35. # 将python对象转换为json字符串(格式化返回数据)
    36. result = json.dumps(response.json(), indent=2, ensure_ascii=False)
    37. # print(type(result)) # 字符串类型
    38. print(result)
    39. """
    40. 返回结果:
    41. {
    42. "args": {},
    43. "data": "",
    44. "files": {},
    45. ****************主要看这里
    46. "form": {
    47. "dep_id": "T01",
    48. "dep_name": "Test学院",
    49. "master_name": "Test-Master",
    50. "slogan": "Here is Slogan"
    51. },
    52. ***********************
    53. "headers": {
    54. "Accept": "*/*",
    55. "Accept-Encoding": "gzip, deflate",
    56. "Content-Length": "88",
    57. *****************主要看这里
    58. "Content-Type": "application/x-www-form-urlencoded",
    59. *****************
    60. "Host": "httpbin.org",
    61. "User-Agent": "python-requests/2.18.4",
    62. "X-Amzn-Trace-Id": "Root=1-5ff401e3-1553596b7788e77e275c4772"
    63. },
    64. "json": null,
    65. "origin": "106.35.9.12",
    66. "url": "http://httpbin.org/post"
    67. }
    68. """

    说明:

    • 发送的请求中,form属性接收了参数。
    • 在请求头中,Content-Type属性为application/x-www-form-urlencoded
    • 使用application/x-www-form-urlencoded格式发送数据,requests.post(url=url, data=data)方法中一定要使用data变量来接收参数。
    • 换句话说数据格式是字典格式,使用data变量来接收,会默认发送application/x-www-form-urlencoded数据格式的POST请求。(也可以在请求头中明确一下Content-Type属性,但没必要。)

    2、请求正文是raw

    RAW的原意就是“未经加工”。换句话说RAW方式使用的是纯字符串的数据上传方式,所以在发送POST请求之前,可能需要手工的把一些JSON格式的数据转换成字符串的(加两单引号),在进行提交。
    RAW数据格式的POST请求有两种:

    • 一种是xml格式文本(text/xml)
    • 一种是json格式文本(application/json)

    下面我们一一说明:
    (1)json格式文本(application/json)

    1. # 1.导入requests库
    2. import requests
    3. import json
    4. # 2.明确请求地址
    5. url = "http://httpbin.org/post"
    6. # 3.明确请求参数
    7. data = {
    8. "data": [
    9. {
    10. "dep_id": "T01",
    11. "dep_name": "Test学院",
    12. "master_name": "Test-Master",
    13. "slogan": "Here is Slogan"
    14. }
    15. ]
    16. }
    17. # headers = {"Content-Type": "application/json"}
    18. # 4.发送请求
    19. response = requests.post(url=url, json=data)
    20. print(response) # <Response [200]>
    21. print(response.text)
    22. """
    23. 返回结果:
    24. {
    25. "args": {},
    26. "data": "{\"data\": [{\"dep_id\": \"T01\", \"dep_name\": \"Test\\u5b66\\u9662\", \"master_name\": \"Test-Master\", \"slogan\": \"Here is Slogan\"}]}",
    27. "files": {},
    28. "form": {},
    29. "headers": {
    30. "Accept": "*/*",
    31. "Accept-Encoding": "gzip, deflate",
    32. "Content-Length": "119",
    33. **************************主要看这里
    34. "Content-Type": "application/json",
    35. **************************
    36. "Host": "httpbin.org",
    37. "User-Agent": "python-requests/2.18.4",
    38. "X-Amzn-Trace-Id": "Root=1-5ff40a9d-6a6f19d272ba4c1b40ff7bbb"
    39. },
    40. **************************主要看这里
    41. "json": {
    42. "data": [
    43. {
    44. "dep_id": "T01",
    45. "dep_name": "Test\u5b66\u9662",
    46. "master_name": "Test-Master",
    47. "slogan": "Here is Slogan"
    48. }
    49. ]
    50. },
    51. **************************
    52. "origin": "106.35.9.12",
    53. "url": "http://httpbin.org/post"
    54. }
    55. """


    说明:

    • 发送的请求中,json属性接收了参数。
    • 在请求头中,Content-Type属性为application/json
    • 使用application/json格式发送数据,requests.post(url=url, json=data)方法中一定要使用json变量来接收参数。
    • 换句话说数据格式是Json格式,使用json变量来接收,Requests会默认发送application/json数据格式的POST请求。(也可以在请求头中明确一下Content-Type属性,但没必要。)
    注意:
    这里我们可以发现Requests模拟post请求时,请求头格式为application/x-www-form-urlencoded与application/json的主要差别在于请求主体的构造格式(前者是键值对,后者是JSON串),前者直接用字典传入,后者用json.dumps()函数将字典转为JSON串即可。
    也就是说在有需要的时候json模块下的dumps函数可以将dict转换为str。

    (2)xml格式文本(text/xml)

    1. # 1.导入requests库
    2. import requests
    3. import json
    4. # 2.明确请求地址
    5. url = "http://httpbin.org/post"
    6. # 3.明确请求参数
    7. data = '' \
    8. '' \
    9. '菜鸟教程' \
    10. 'www.runoob.com' \
    11. '' \
    12. '' \
    13. 'Google' \
    14. 'www.google.com' \
    15. '' \
    16. ''
    17. # requests.post方法中适用json变量来接收数据,
    18. # 默认是"Content-Type": "application/json",
    19. # 这里我们需要重新声明一下Content-Type属性。
    20. headers = {'Content-type': 'text/xml'}
    21. # 4.发送请求
    22. # 如果数据用data变量来接收会报错。
    23. response = requests.post(url=url, json=data, headers=headers)
    24. print(response) # <Response [200]>
    25. # print(response.text)
    26. # 将python对象转换为json字符串(格式化返回数据)
    27. result = json.dumps(response.json(), indent=2, ensure_ascii=False)
    28. # print(type(result)) # 字符串类型
    29. print(result)
    30. """
    31. 返回结果:
    32. {
    33. "args": {},
    34. "data": "\"\\u83dc\\u9e1f\\u6559\\u7a0bwww.runoob.comGooglewww.google.com\"",
    35. "files": {},
    36. "form": {},
    37. "headers": {
    38. "Accept": "*/*",
    39. "Accept-Encoding": "gzip, deflate",
    40. "Content-Length": "149",
    41. **************************主要看这里
    42. "Content-Type": "text/xml",
    43. **************************
    44. "Host": "httpbin.org",
    45. "User-Agent": "python-requests/2.18.4",
    46. "X-Amzn-Trace-Id": "Root=1-5ff40fa5-21a79b532b1ccf6d20173fd7"
    47. },
    48. **************************主要看这里
    49. "json": "<sites><site><name>菜鸟教程</name><url>www.runoob.com</url></site><site><name>Google</name><url>www.google.com</url></site></sites>",
    50. **************************
    51. "origin": "106.35.9.12",
    52. "url": "http://httpbin.org/post"
    53. }
    54. """

    说明:

    • text/xml格式相对用的少。
    • xml也可以作为一个文件来传输。
    • 需要重新声明请求头中Content-Type属性。
    • 其他和application/json一样。

    提示:其实raw格式数据可以上传text、json、xml、html等纯字符的文本。

    3、正文是binary

    使用binary格式的正文发送POST请求,是直接使用二进制流进行数据传输,多用于上传单个图片或图片。
    也可以用于把请求的参数放入一个文件中,进行数据的提交。
    示例如下:

    1. """
    2. 1.学习目标
    3. 掌握requests发送post请求
    4. 2.HTTP协议中post请求参数类型
    5. x-www-form-data-urlencoded
    6. raw_json格式
    7. form-data
    8. binary
    9. 3.binary格式
    10. # 1.明确请求地址
    11. # 2.明确请求参数
    12. data = {"files":open("文件名","rb")} 字典格式
    13. # 3.发送请求
    14. requests.post(url= url,files=data)
    15. 4.需求
    16. http://httpbin.org/post
    17. """
    18. # 1.导入requests
    19. import requests
    20. # 2.请求地址
    21. url = "http://httpbin.org/post"
    22. # 3.请求参数
    23. # 读取文件中的数据作为参数进行提交。
    24. # key位置要写files,是规范
    25. # 也可以写其他的名字,不规范
    26. data = {"files": open("test.txt", "rb")}
    27. # 4.发送请求
    28. response = requests.post(url=url, files=data)
    29. print(response.text)
    30. """
    31. 请求结果如下:
    32. {
    33. "args": {},
    34. "data": "",
    35. **************************主要看这里
    36. "files": {
    37. "files": "username=\u5927\u5c0f\u59d0\r\npassword=test123456\r\nage=18"
    38. },
    39. **************************
    40. "form": {},
    41. "headers": {
    42. "Accept": "*/*",
    43. "Accept-Encoding": "gzip, deflate",
    44. "Content-Length": "192",
    45. **************************主要看这里
    46. "Content-Type": "multipart/form-data; boundary=351e0b73ea144694a9e9fdd1e10d2486",
    47. **************************
    48. "Host": "httpbin.org",
    49. "User-Agent": "python-requests/2.18.4",
    50. "X-Amzn-Trace-Id": "Root=1-5ff499ea-7ad42c4e6f056b44347b3c26"
    51. },
    52. "json": null,
    53. "origin": "106.35.9.12",
    54. "url": "http://httpbin.org/post"
    55. }
    56. """

    说明:

    • 发送的请求中,files属性接收了参数。
    • 在请求头中,Content-Type属性为multipart/form-data
    • 使用application/json格式发送数据,requests.post(url=url, files=data)方法中一定要使用files变量来接收参数。
    • 换句话说Requests也支持发送binary数据形式的POST请求,只需将文件传给requests.post()方法的files参数即可。

    4、multipart/form-data

    multipart/form-data数据格式的POST请求,多用于文件上传。
    示例1:

    1. """
    2. 1.学习目标
    3. 掌握requests发送post请求
    4. 2.HTTP协议中post请求参数类型
    5. x-www-form-data-urlencoded
    6. raw_json格式
    7. form-data
    8. binary
    9. 3.form-data格式
    10. 使用files变量来接收数据,默认是使用form-data格式发送POST请求。
    11. 4.需求
    12. http://httpbin.org/post
    13. """
    14. import requests
    15. files = {'file1': open('logo.png', 'rb')}
    16. response = requests.post('http://127.0.0.1:9999/post', files=files)
    17. print(response.text)
    18. """
    19. 接口返回结果:
    20. {
    21. "args": {},
    22. "data": "",
    23. **************************主要看这里
    24. "files": {
    25. "file1": "data:application/octet-stream;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHerOCtwJPHpvQjoYqxmHighE/wO1YuuATgOKt9wGMd653WXlhe2xbcpauJjePjQYuZTOOk032eaYj+GgOQ+E1QCBj4UxtunNUFIjBmm5P05oBjLv99qoKgEpW9PSu1b0tAglXYOr2/uN4rtp6ZZay53n81IAlauN/pRH/2Q=="
    26. },
    27. **************************
    28. "form": {},
    29. "headers": {
    30. "Accept": "*/*",
    31. "Accept-Encoding": "gzip, deflate",
    32. "Connection": "keep-alive",
    33. "Content-Length": "394145",
    34. **************************主要看这里
    35. "Content-Type": "multipart/form-data; boundary=4efea05a2cf34e78a75508a1ebf000ec",
    36. **************************
    37. "Host": "127.0.0.1:9999",
    38. "User-Agent": "python-requests/2.18.4"
    39. },
    40. "json": null,
    41. "origin": "127.0.0.1",
    42. "url": "http://127.0.0.1:9999/post"
    43. }
    44. """

    示例2:
    我们也可以显式地设置文件名,文件类型和请求头:

    1. import requests
    2. # hangge.png 为图片名称
    3. files = {'file1': ('hangge.png', open('logo.png', 'rb'), 'image/png', {'Expires': '0'})}
    4. response = requests.post('http://127.0.0.1:9999/post', files=files)
    5. print(response.text)
    6. """
    7. 接口返回结果:
    8. {
    9. "args": {},
    10. "data": "",
    11. **************************主要看这里
    12. "files": {
    13. "file1": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyacMkc0Yyc0UAf/Z"
    14. },
    15. **************************
    16. "form": {},
    17. "headers": {
    18. "Accept": "*/*",
    19. "Accept-Encoding": "gzip, deflate",
    20. "Connection": "keep-alive",
    21. "Content-Length": "7063",
    22. **************************主要看这里
    23. "Content-Type": "multipart/form-data; boundary=382e06cba6834118a1f1efd0ea2c45e3",
    24. **************************
    25. "Host": "127.0.0.1:9999",
    26. "User-Agent": "python-requests/2.18.4"
    27. },
    28. "json": null,
    29. "origin": "127.0.0.1",
    30. "url": "http://127.0.0.1:9999/post"
    31. }
    32. """

    示例3:多文件上传
    有时我们需要在一个请求中同时发送多个文件,同样使用 files 参数传入一个数组即可:

    1. import requests
    2. files = [
    3. ('file1', ('1.png', open('logo.png', 'rb'), 'image/png')),
    4. ('file2', ('2.png', open('logo.png', 'rb'), 'image/png'))
    5. ]
    6. response = requests.post('http://127.0.0.1:9999/post', files=files)
    7. print(response.text)
    8. """
    9. 接口返回结果:
    10. {
    11. "args": {},
    12. "data": "",
    13. **************************主要看这里
    14. "files": {
    15. "file1": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgc3p8zdacMkc0Yyc0UAf/Z",
    16. "file2": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgc3p8zdacMkc0Yyc0UAf/Z"
    17. },
    18. **************************
    19. "form": {},
    20. "headers": {
    21. "Accept": "*/*",
    22. "Accept-Encoding": "gzip, deflate",
    23. "Connection": "keep-alive",
    24. "Content-Length": "14054",
    25. **************************主要看这里
    26. "Content-Type": "multipart/form-data; boundary=ba662835a2364b069c99ba3ffa56b974",
    27. **************************
    28. "Host": "127.0.0.1:9999",
    29. "User-Agent": "python-requests/2.18.4"
    30. },
    31. "json": null,
    32. "origin": "127.0.0.1",
    33. "url": "http://127.0.0.1:9999/post"
    34. }
    35. """

    示例4:上传时附带其它参数
    如果我们需要在上传文件的同时传递一些其它参数,也是可以的:

    1. import requests
    2. data = {
    3. "name": "ABC.com",
    4. "age": 100
    5. }
    6. files = [
    7. ('file1', ('1.png', open('logo.png', 'rb'), 'image/png')),
    8. ('file2', ('2.png', open('logo.png', 'rb'), 'image/png'))
    9. ]
    10. response = requests.post('http://127.0.0.1:9999/post', data=data, files=files)
    11. print(response.text)
    12. """
    13. 接口返回结果:
    14. {
    15. "args": {},
    16. "data": "",
    17. **************************主要看这里
    18. "files": {
    19. "file1": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDA0Yyc0UAf/Z",
    20. "file2": "data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDA0Yyc0UAf/Z"
    21. },
    22. "form": {
    23. "age": "100",
    24. "name": "ABC.com"
    25. },
    26. **************************
    27. "headers": {
    28. "Accept": "*/*",
    29. "Accept-Encoding": "gzip, deflate",
    30. "Connection": "keep-alive",
    31. "Content-Length": "14233",
    32. **************************主要看这里
    33. "Content-Type": "multipart/form-data; boundary=6bdedbde2b48465683ef4e3451f7e015",
    34. **************************
    35. "Host": "127.0.0.1:9999",
    36. "User-Agent": "python-requests/2.18.4"
    37. },
    38. "json": null,
    39. "origin": "127.0.0.1",
    40. "url": "http://127.0.0.1:9999/post"
    41. }
    42. """

    示例5:流式上传文件

    • 有时我们需要上传一个非常大的文件(比如 1G 左右),如果像上面的方式直接使用 Requests提交,可能会造成内存不足而崩溃。
    • 所以发送大文件时还是建议将请求做成数据流。不过默认下 Requests 不支持流式上传,但有个第三方包 requests-toolbelt 是支持的(本质还是 multipart/form-data 上传)
    • 在使用 requests-toolbelt 之前,我们首先通过 pip 进行安装:
    1. # cmd命令行终端执行如下命令。
    2. pip install requests-toolbelt

    练习如下:

    1. """
    2. 1.学习目标
    3. 掌握requests发送post请求
    4. 2.HTTP协议中post请求参数类型
    5. x-www-form-data-urlencoded
    6. raw_json格式
    7. form-data
    8. binary
    9. 3.form-data格式
    10. # 1.导入requests库,requests_toolbelt库
    11. # 2.明确请求地址
    12. # 3.明确请求参数
    13. data = {} 字典格式
    14. 对请求参数加工(实例化)
    15. m = MultipartEncoder(fields = data)
    16. # 4.添加请求头
    17. headers = {"Content_Type":m.content_type}
    18. # 5.发送请求
    19. requests.post(url= url,data=m,headers=headers)
    20. 4.需求
    21. http://httpbin.org/post
    22. """
    23. # 1.导入requests库
    24. import requests
    25. from requests_toolbelt import MultipartEncoder
    26. # from requests_toolbelt.multipart.encoder import MultipartEncoder
    27. # 2.明确请求地址
    28. url = "http://httpbin.org/post"
    29. # 3.明确请求参数
    30. data = {
    31. "username": "Jerry",
    32. "password": "1232456",
    33. "sex": "男"
    34. }
    35. # requests-toolbelt 还提供了个监视器(MultipartEncoderMonitor),
    36. # 该监视器接受一个回调函数,我们可以在回调中实时跟踪进度。
    37. # from requests_toolbelt import MultipartEncoderMonitor
    38. # def my_callback(monitor):
    39. # progress = (monitor.bytes_read / monitor.len) * 100
    40. # print("\r 文件上传进度:%d%%(%d/%d)"
    41. # % (progress, monitor.bytes_read, monitor.len), end=" ")
    42. # m = MultipartEncoder(
    43. # fields={'name': 'ABC.com', "age": '100',
    44. # 'file1': ('1.png', open('logo.png', 'rb'), 'image/png'),
    45. # 'file2': ('2.png', open('logo.png', 'rb'), 'image/png')}
    46. # )
    47. # 4.添加请求头和加工请求参数
    48. # 加工请求参数----让每个参数都要带有边界
    49. m = MultipartEncoder(fields=data)
    50. # 添加请求头
    51. headers = {"Content_Type": m.content_type}
    52. # 4.发送请求
    53. response = requests.post(url=url, data=m, headers=headers)
    54. print(response.text)
    55. """
    56. 请求结果:
    57. {
    58. "args": {},
    59. "data": "",
    60. "files": {},
    61. **************************主要看这里
    62. "form": {
    63. "username": "Jerry",
    64. "password": "1232456",
    65. "sex": ""
    66. },
    67. **************************
    68. "headers": {
    69. "Accept": "*/*",
    70. "Accept-Encoding": "gzip, deflate",
    71. "Content-Length": "192",
    72. **************************主要看这里
    73. "Content-Type": "multipart/form-data; boundary=351e0b73ea144694a9e9fdd1e10d2486",
    74. **************************
    75. "Host": "httpbin.org",
    76. "User-Agent": "python-requests/2.18.4",
    77. "X-Amzn-Trace-Id": "Root=1-5ff499ea-7ad42c4e6f056b44347b3c26"
    78. },
    79. "json": null,
    80. "origin": "106.35.9.12",
    81. "url": "http://httpbin.org/post"
    82. }
    83. """

    5、总结Binary和Form-data区别

    主要区别在于:

    • Binary只可以上传二进制数据,通常用来上传文件,由于没有键值,所以一次只能上传一个文件,而Form-data可以传多个。
    • Form-data既可以上传文件等二进制数据,也可以上传表单键值对。利用key-value对,可以分别对每个文件进行描述。

    最后:下面是配套学习资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!【100%无套路免费领取】

    软件测试面试小程序

    被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

    涵盖以下这些面试题板块:

    1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

    6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

      全套资料获取方式:点击下方小卡片自行领取即可

  • 相关阅读:
    带你一步步看vue-loader编译流程
    被环境变量虐过一遍获得的启示
    【JVM面试题】JVM分代年龄为何是15次?能设置为16吗?
    安装JAVA和java IDEA并汉化过程
    springboot基于web的游泳馆信息管理系统毕业设计源码281444
    [附源码]java毕业设计置地房屋租赁信息系统
    Rebex Total Pack R6.9 Crack
    面向OLAP的列式存储DBMS-10-[ClickHouse]的常用数组操作
    初试scikit-learn库
    人血清白蛋白功能化纳米四氧化三铁Fe3O4
  • 原文地址:https://blog.csdn.net/weixin_57794111/article/details/133882649