def requestsMethodForPost(param):
url = upGradeUrl + '?'
request = requests.post(url, data=param)
response = request.text
print response
respDic = json.loads(response)
return respDic
大神们,我用 python 做接口自动化测试,遇到这么一个问题,在用 requests 中 post 请求的时候,参数中会带有中文,然后我就直接把中文传进去了:
params = {
'from':'internal',
'gps_type':'baidu',
'lat':'40.018597',
'lng':'116.476326',
'mac':'b4:30:52:5e:6d:61',
'model':'HUAWEI-HUAWEI C8817E',
'name':'先生',
'order_id':self.order_id,
'os':'HUAWEI19,4.4.4',
'phone':'13000000090',
}
然后,我就 post 出这个请求,但是在控制台,这个中文被直接自动转换为'\xe5\x85\x88\xe7\x94\x9f',导致这个传参一直是错误的,服务端会去校验你传入的值是否为正确编码格式,而 python 默认不会直接传入中文数据,这个有人遇到过吗
假如服务端是接受 GBK 编码,对于 python 3 来说,中文 POST 参数应这样写
```python 3
#requests (2.18.4)
'name': '先生'.encode('GBK'), # 生成 bytes 类型,而不要用 str。因为 str 会默认由 utf-8 编码。如果服务端也用 UTF-8 解码中文,应该不会有问题。
以下是models.py原文 在site-packages\requests 目录下
```python
def _encode_params(data):
"""Encode parameters in a piece of data.
Will successfully encode parameters when passed as a dict or a list of
2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
if parameters are supplied as a dict.
"""
if isinstance(data, (str, bytes)):
return data
elif hasattr(data, 'read'):
return data
elif hasattr(data, '__iter__'):
result = []
for k, vs in to_key_val_list(data):
if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
vs = [vs]
for v in vs:
if v is not None:
result.append(
(k.encode('utf-8') if isinstance(k, str) else k,
v.encode('utf-8') if isinstance(v, str) else v))
return urlencode(result, doseq=True)
else:
return data
关键位置在于对 k,v 的处理,所以假如提供的是,b'\xcf\xc8\xc9\xfa' 这样的数据,会原样传给服务器。
但是假如服务器也是 UTF-8 处理中文,则完全不用这样。这样服务器接收到的 name 值就是'先生'.encode('utf-8') .也许是 b'\xe5\x85\x88\xe7\x94\x9f'。
然后它还要经过 urldecode 处理以后,再反向解析成中文字符串。就是你看到的这个样子'\xe5\x85\x88\xe7\x94\x9f' 这就是 name 参数的内存格式。
假如控制台只能接受和显示 GB2312、 要对这个字符串做 utf-8 转 GBK 的处理才能显示出来了。
这是两个关于汉字编码的地址可做参考
http://www.cnblogs.com/ttltry-air/p/3325543.html
https://www.zhihu.com/question/26921730
感觉这个跟 post 请求没关系,看看有没有在文件开头加上 #coding=utf-8
—— 来自 TesterHome 官方 安卓客户端
'name':u'先生',
试一下。
可以使用 fiddler 抓包下你 post 的数据,查看下是否正确。Inspectors→webForms→bodydata
编码编码,格式转换,你先问一下,接口接受的默认编码是啥子,然后转换你的参数后在传递
我觉得接口测试中,你还要考虑加解密的封装,正则匹配,特别是断言的正则匹配
json.dumps( params, ensure_ascii = False, separators = (',', ':') )
对了,多问您一句,您平时断言怎么写的,比如正常接口返回值 code=0,然后当我任意传递参数不正确的时候返回 code 值为 1,那我断言就写一个正确的传参用例和几个错误的传参用例,当错误的时候,self.assertEqual(respDic['code'],1),符合预期用例通过,但是,明显的我服务器这时候是有问题的啊,他返回非零就是有问题的但是我用例跑通过了,这如何能抓到服务的错误,感觉很矛盾啊
换 python 3 试试
python3 网上说是可以的,但是如果换的话感觉有些格式的编写就需要修改,不是太方便,当然也是可以解决这个问题的,辛苦
我试了下目前情况是这样的,接口测试用 post 请求的时候,当我直接打印 param 中的信息的时候,中文就直接被转为 16 进制了,当我 param['name'] 的时候,就会打印出中文,很纳闷啊
把中文先编码,然后再组装到 json 里试试
假如服务端是接受 GBK 编码,对于 python 3 来说,中文 POST 参数应这样写
```python 3
#requests (2.18.4)
'name': '先生'.encode('GBK'), # 生成 bytes 类型,而不要用 str。因为 str 会默认由 utf-8 编码。如果服务端也用 UTF-8 解码中文,应该不会有问题。
以下是models.py原文 在site-packages\requests 目录下
```python
def _encode_params(data):
"""Encode parameters in a piece of data.
Will successfully encode parameters when passed as a dict or a list of
2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
if parameters are supplied as a dict.
"""
if isinstance(data, (str, bytes)):
return data
elif hasattr(data, 'read'):
return data
elif hasattr(data, '__iter__'):
result = []
for k, vs in to_key_val_list(data):
if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
vs = [vs]
for v in vs:
if v is not None:
result.append(
(k.encode('utf-8') if isinstance(k, str) else k,
v.encode('utf-8') if isinstance(v, str) else v))
return urlencode(result, doseq=True)
else:
return data
关键位置在于对 k,v 的处理,所以假如提供的是,b'\xcf\xc8\xc9\xfa' 这样的数据,会原样传给服务器。
但是假如服务器也是 UTF-8 处理中文,则完全不用这样。这样服务器接收到的 name 值就是'先生'.encode('utf-8') .也许是 b'\xe5\x85\x88\xe7\x94\x9f'。
然后它还要经过 urldecode 处理以后,再反向解析成中文字符串。就是你看到的这个样子'\xe5\x85\x88\xe7\x94\x9f' 这就是 name 参数的内存格式。
假如控制台只能接受和显示 GB2312、 要对这个字符串做 utf-8 转 GBK 的处理才能显示出来了。
这是两个关于汉字编码的地址可做参考
http://www.cnblogs.com/ttltry-air/p/3325543.html
https://www.zhihu.com/question/26921730
您好,python requests 接口测试,根据 postman 得到的参数 payload 里还有中文,执行后会报错。UnicodeEncodeError: 'latin-1' codec can't encode characters in position 179-182: Body ('并驾齐驱') is not valid Latin-1. Use body.encode('utf-8') if you want to send it encoded in UTF-8.请问大牛是怎么解决的?
上边的说法都试了一遍,为啥还是不行,请求发送之后还是 byte 格式