1. 程式人生 > 其它 >python+pytest介面自動化(5)-傳送post請求

python+pytest介面自動化(5)-傳送post請求

簡介

在HTTP協議中,與get請求把請求引數直接放在url中不同,post請求的請求資料需通過訊息主體(request body)中傳遞。

且協議中並沒有規定post請求的請求資料必須使用什麼樣的編碼方式,所以其請求資料可以有不同的編碼方式,服務端通過請求頭中的Content-Type欄位來獲知請求中的訊息主體是何種編碼方式,再以對應方式對訊息主體進行解析。

post請求引數常用的編碼方式如下:

application/x-www-form-urlencoded		                # form表單格式,非常常見
multipart/form-data						# 一般用於上傳檔案,較為常見
application/json						# json字串格式,非常常見
text/xml							# xml格式

關於post請求引數,後面會有文章專門講述,這裡不做過多的闡述。

requests.post()引數說明

使用requests庫提供的post方法傳送post請求,requests.post()原始碼如下:

def post(url, data=None, json=None, **kwargs):
    r"""Sends a POST request.

    :param url: URL for the new :class:`Request` object.
    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
        object to send in the body of the :class:`Request`.
    :param json: (optional) json data to send in the body of the :class:`Request`.
    :param \*\*kwargs: Optional arguments that ``request`` takes.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response
    """

    return request('post', url, data=data, json=json, **kwargs)

引數說明:

  1. url,請求網址
  2. data,字典、元組列表、位元組或要傳送到指定URL的檔案物件,可選(即可填可不填)
  3. json,要傳送到指定URL的JSON物件,可選
  4. **kwargs,可以新增其他請求引數,如headers、timeout、cookies等

post介面中常用的編碼格式在python指令碼中對應的請求引數的格式一般就是 dict (字典) 或 json,如application/x-www-form-urlencoded格式在python中對應為dict,application/json在python中對應為json。

因此,接下來分別這種編碼格式進行舉例。

傳送post請求(請求引數格式為dict)

我們以請求TesterHome網的登入介面為例,傳送請求引數格式為dict的請求。

請求頭中content-type為application/x-www-form-urlencoded;charset=UTF-8,如下圖所示:

那麼請求引數編碼格式應為dict,程式碼如下:

import requests

def testerhome_login():
    # data為請求入參
    data = {
        "user[login]": "賬號",
        "user[password]": "密碼",
        "user[remember_me]": 0,
        "commit": "登入"
    }
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/53\
        7.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36"
    }
    url = "https://testerhome.com/account/sign_in"
    
    # 編碼格式為application/x-www-form-urlencoded;charset=UTF-8,所以請求引數為dict,使用data引數
    res = requests.post(url=url, headers=headers, data=data)
    print(res.text)
    print(res.status_code)


if __name__ == '__main__':
    testerhome_login()

執行結果如下:

由打印出來的返回內容,我們可以判斷該介面請求成功。

傳送post請求(請求引數格式為json)

這裡我用flask框架寫了個簡單的模擬介面來演示,介面程式碼如下:

from flask import Flask, jsonify, request

app = Flask(__name__)
app.config["JSON_AS_ASCII"] = False

@app.route("/login", methods=["POST"])
def login():
    username = request.json.get("username").strip()
    password = request.json.get("password").strip()
    print(username, password)
    if username and password:
        if username == "lilei" and password == "123456":
            return jsonify(
                {"code": 1000, "msg": "登入成功!", "token": "sh34ljjl08s32730dj"}
            )
        elif username == "hanmeimei" and password == "888888":
            return jsonify(
                {"code": 1000, "msg": "登入成功!", "token": "hjf078977l08ert2323k"}
            )
        else:
            return jsonify(
                {"code": 1001, "msg": "賬號或密碼錯誤!"}
            )
    else:
        return jsonify(
            {"code": 1002, "msg": "賬號或密碼不能為空!"}
        )

if __name__ == '__main__':
    app.run()

注意需要先安裝flask框架,然後執行該模組,具體可參考我之前的文章使用Flask開發簡單介面,執行後我們可以看到該介面服務的 host 地址,如下:

這個介面的請求引數格式需要為jsonrequests.post()請求這個介面程式碼如下:

import requests
import json

headers = {"Content-Type": "application/json;charset=utf8"}
url = "http://127.0.0.1:5000/login"
_data = {
    "username": "lilei",
    "password": "123456"
}

# 這裡使用json引數,即json=_data
res = requests.post(url=url, headers=headers, json=_data).text
# 當然還可以使用data引數,但需先將_data轉換為json格式,即data=json.dumps(_data)
# json.dumps()將dict格式轉換成json格式
res = requests.post(url=url, headers=headers, data=json.dumps(_data)).text
print(res)

執行結果如下:

總結

post請求因為請求主體編碼格式的原因,在使用requests.post()時需要根據介面請求頭中Content-Type欄位,為請求引數選擇指定的編碼格式,才能傳送請求。其實get請求的請求引數也有其對應的編碼格式,至於如何確定get、post請求引數的格式,且聽下回詳解。