Python 写接口时编码问题
HDUZN

想写个简单的接口,有了api2d的key(就像有了openai的key一样),可以调用API了,就简单写个接口当服务器用。

用的Web框架是Bottle,跟Flask用法一样,也是路由、视图那一套。只是简单的一个聊天接口,所以就用了这个更微型的。
用法:Python Bottle框架使用举例

写好接口,用 Requests 进行测试时发现,编码有问题,响应的结果老是乱码。

Python Requests 使用举例

在GPT3.5 上问了老半天,来回就那几种方法,编码解码的,试来试去都不行。响应结果就是乱码,不管是Get请求,还是Post请求,都乱码。

心一横,用GPT4 问了一下,好家伙,两次回答就解决了。(就是费token)

Get请求接口举例

运行后,直接在浏览器 http://localhost:8080/chat?q=来首唐诗 访问,就可以看到响应的结果了。

解决乱码问题的关键是getunicode方法question = request.query.getunicode('q') 这样会自动处理编码问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from bottle import Bottle, request, response
import json

app = Bottle()

# http://localhost:8080/chat?q=来首唐诗
@app.route('/chat', method='GET')
def chat():
# 获取请求中的数据, getunicode方法会自动处理编码问题
# question = request.query.get('q')
question = request.query.getunicode('q')

# 处理输入话语,根据业务逻辑构建响应数据
result = question + ":test----22222" # 这里只是随便举例

# 处理数据,这里简单地返回固定的响应数据
response_data = {
'message': 'Success',
'answer': result
}

# 设置响应的 Content-Type 为 JSON
# response.content_type = 'application/json'
# 设置响应的 Content-Type 为 JSON,并指定编码为 UTF-8
response.headers['Content-Type'] = 'application/json; charset=utf-8'

# 返回 JSON 响应, 序列化成 JSON字符串
# return response_data
return json.dumps(response_data, ensure_ascii=False)

if __name__ == '__main__':
app.run(host='localhost', port=8080)

涉及 JSON的序列化内容详解可以看这篇:Python JSON使用举例

Post请求接口举例

跟在Get请求中也是一样的,用getunicode方法question = request.forms.getunicode('question') 这样会自动处理编码问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from bottle import Bottle, request, response
import json, http.client

app = Bottle()

@app.route('/chat', method='POST')
def chat():
# 获取查询参数中的输入话语,getunicode方法会自动处理编码问题
question = request.forms.getunicode('question')

# 处理输入话语,根据业务逻辑构建响应数据
# question = "床前明月光"
result = question + ":test----22222"
# print(result)

response_data = {
'message': 'Success',
'answer': result
}

# 设置响应的 Content-Type 为 JSON,并指定编码为 UTF-8
response.headers['Content-Type'] = 'application/json; charset=utf-8'

# 返回 JSON 响应,ensure_ascii=False 返回的JSON字符串中的非ASCII字符不会被转义
return json.dumps(response_data, ensure_ascii=False)

if __name__ == '__main__':
app.run(host='localhost', port=8080)

json参数与data参数区别

Post 请求时,发现如果调用的时候用的是 json 参数:response = requests.post(url, json={'question': '今天天气'})
如果是data参数: response = requests.post(url, data={'question': '今天天气'})

在requests库中,jsondata参数都可以用于发送POST请求的请求体数据,但它们的使用方式和数据格式有所不同。

1.json参数

  • 使用 json 参数时,可以将一个Python对象(通常是字典)作为参数传递给 json ,requests库会自动将其转换为JSON格式,并将其作为请求体发送。
  • json 参数会自动设置请求头中的Content-Typeapplication/json,表示请求体中的数据为JSON格式。
  • 这种方式适用于与API进行交互,特别是需要发送JSON格式数据的情况。
  • 例如,当向一个创建用户的接口发送用户信息时,可以使用json参数将数据以JSON格式发送。
    1
    2
    3
    4
    5
    6
    7
    8
    import requests
    import json

    data = {'name': 'John Doe', 'age': 25}
    headers = {'Content-Type': 'application/json'}

    response = requests.post('https://api.example.com/user', json=data, headers=headers)
    print(response.status_code)

    2.data参数

  • 使用 data 参数时,可以将一个字典对象作为参数传递给 data ,requests库会自动将其转换为URL编码格式,并将其作为请求体发送。
  • data 参数不会自动设置请求头中的Content-Type,默认为application/x-www-form-urlencoded,表示请求体中的数据为URL编码格式。
  • 这种方式适用于与传统的Web表单进行交互,特别是需要发送URL编码格式数据的情况。
  • 例如,当向一个登录接口发送用户名和密码时,可以使用data参数将数据以URL编码格式发送。
    1
    2
    3
    4
    5
    import requests

    data = {'username': 'admin', 'password': '123456'}
    response = requests.post('https://api.example.com/login', data=data)
    print(response.status_code)
    总结:
  • json 参数适用于与API进行交互,发送JSON格式的数据。自动设置请求头为application/json
  • data 参数适用于适用于与传统的Web表单进行交互,发送URL编码格式的数据。不会自动设置请求头,默认为application/x-www-form-urlencoded
  • 本文标题:Python 写接口时编码问题
  • 本文作者:HDUZN
  • 创建时间:2023-06-29 14:53:03
  • 本文链接:http://hduzn.cn/2023/06/29/Python写接口时编码问题/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论