用谷歌浏览器自带的调试工具查看网页请求,再用Postman来模拟请求,最后再用requests实现。但是这几步骤之间可能有一些问题。
key-value的坑
如果你直接从F12调试工具中复制请求内容,然后以Bulk Edit
的形式复制到Postaman中,你很有可能发现请求体完全一样,但就是返回400等错误数据。这是因为忽视了key-value中的空格,Bulk Edit
转换为键值对的形式时,空格保留了下来,因此你的数据上传到后台比较后发现不匹配,自然得不到正确数据。这要看服务器会不会去忽视那些空格。
x-www-form-urlencoded
与form-data
能用x-www-form-urlencoded
形式尽量使用,requests库对form-data
支持不友好。
对于下面这种需要用form-data
形式提交的数据,用这样的方法会得不到数据。
params = {
'timestamp':timestamp,
'nonce':nonce,
'apikey':APIKEY,
'signature': signature
}
data = {
'name': name,
'phone': phone,
'idnum': idnum,
'products': [201,]
}
resp = requests.post(URL, data=data, params=params,
verify=False, timeout=10)
在这里提供两种方法:
方案一:手动构造
就是手动把form-data
数据形式表现出来,不推荐,代码不简洁,看得眼花缭乱。
params = {
'timestamp':timestamp,
'nonce':nonce,
'apikey':APIKEY,
'signature': signature
}
payload = """------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data;
name=\"phone\"\n\n{}\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data;
name=\"idnum\"\n\n{}\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data;
name=\"name\"\r\n\r\n{}\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data;
name=\"products\"\r\n\r\n {}\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--""".format(phone, idnum, name, [201,])
headers = {
"content-type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
}
resp = requests.post(URL, data=payload, params=params,
verify=False, timeout=10, headers=headers)
方案二:通过files参数传递form-datal
推荐使用
import json
params = {
'timestamp':timestamp,
'nonce':nonce,
'apikey':APIKEY,
'signature': signature
}
data = {
'name':(None, name),
'phone': (None, str(phone)),
'idnum': (None, idnum),
'products': (None, json.dumps([201,]))
}
resp = requests.post(URL, files=data, params=params,
verify=False, timeout=10)