最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Python调用接口出错:TypeError string indices must be integers

Python crifan 8027浏览 0评论

折腾:

【已解决】把文本格式的剧本内容用Python批量导入后台系统

期间,用代码:

<code>logging.info("curScriptDict=%s", curScriptDict)
saveScriptResp = requests.post(CreateScriptUrl, headers=gHeaders, data=curScriptDict)
logging.info("saveScriptResp=%s", saveScriptResp)
</code>

结果导致服务器内部500错误:

<code>20180717 11:22:49 BatchImportScript.py:199  INFO    curScriptDict={'operate_mark': 'save', 'place': 'School canteen', 'title': 'Have lunch', 'age_start': 3, 'age_end': 4, 'topic': 'Food', 'second_level_topic': '', 'dialogs': [{'type': '0', 'speaker': 'J', 'content': 'What did you have for lunch?'}, {'type': '0', 'speaker': 'L', 'content': 'I ate rice, fish and bread.'}, {'type': '0', 'speaker': 'J', 'content': 'Do you like rice?'}, {'type': '0', 'speaker': 'L', 'content': 'Yes, I do.'}, {'type': '0', 'speaker': 'J', 'content': 'Do you like fish?'}, {'type': '0', 'speaker': 'L', 'content': 'Yes, I do.'}, {'type': '0', 'speaker': 'J', 'content': 'Do you like bread?'},{'type': '0', 'speaker': 'L', 'content': 'No, I don’t.'}, {'type': '0', 'speaker': 'J', 'content': 'What did you drink?'}, {'type': '0', 'speaker': 'L', 'content': 'I drank milk.'}, {'type': '0', 'speaker': 'J', 'content': 'Do you like milk?'}, {'type': '0', 'speaker':'L', 'content': 'Yes, I do.'}]}
20180717 11:23:10 BatchImportScript.py:201  INFO    saveScriptResp=&lt;Response [500]&gt;
</code>

出错log是:

<code>0_response
    six.reraise(exc_type, exc_value, tb)
  File "/Users/crifan/Library/Python/3.6/lib/python/site-packages/six.py", line 693, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/viewsets.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
    response = self.handle_exception(exc)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/crifan/dev/dev_root/xxx/apps/script/views.py", line 136, in create
    if i['type'] == '0':
TypeError: string indices must be integers
</code>

对应代码查到是:

<code>        script.save()
        # dialog 创建
        dialogs = request.data.get('dialogs', [])
        if dialogs:
            for i in dialogs:
                if i['type'] == '0':
                    dialog = Dialog(type=i['type'], speaker=i['speaker'],
                                    content=i['content'], script=script)
                elif i['type'] == '1':
                    dialog = Dialog(type=i['type'],
                                    audio_file_id=i['audio_file_id'],
                                    audio_file_name=i['audio_file_name'],
                                    script=script)
                dialog.save()
        serializer = ScriptSerializer(script, many=False)
        return Response(serializer.data, status=status.HTTP_201_CREATED)
</code>

看起来自己输出的post的body的json:

貌似没问题啊。

python TypeError string indices must be integers

python错误:TypeError: string indices must be integers – CSDN博客

string indices must be integers –GP调用执行Python时报错 – CSDN博客

“反复测试分析后确定原因:

在.py文件中写的data={“a”:”123″,”b”:”456″},data类型为dict

而在.py文件中通过data= arcpy.GetParameter(0) 获取在GP中传过来的参数{“a”:”123″,”b”:”456″},data类型为字符串!!!

所以在后续的.py中用到的data[‘a’]就会报如上错误!!!”

感觉这个倒是有可能。

突然想到:估计是没有传递content-type是json

导致默认按照txt去解析,所以出错了。去加上试试

此处果然看到了web端提交同样请求时,加上的:

<code>newOptions.headers = {
  Accept: 'application/json',
  'Content-Type': 'application/json; charset=utf-8',
</code>

把自己的此处的header改为:

<code>gHeaders = {
  'Content-Type': 'application/json; charset=utf-8',
  "Accept": 'application/json',
  "Authorization": "",
}
</code>

结果就可以了。

【总结】

此处调用后台接口,但是后台代码:

<code>if i['type'] == '0':
</code>

出错:

TypeError string indices must be integers

的原因是:

此时i是字符串类型,而不是原以为的json dict类型

而之所以变成这样是因为:

调用后台接口时,没有传递

<code>'Content-Type': 'application/json',
</code>

的header,导致服务器后端默认按照text类型去解析。

解决办法:

调用后台接口时加上header:

<code>gHeaders = {
  'Content-Type': 'application/json; charset=utf-8',
  "Accept": 'application/json',
  "Authorization": "",
}
</code>

即可。

转载请注明:在路上 » 【已解决】Python调用接口出错:TypeError string indices must be integers

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
89 queries in 0.185 seconds, using 22.11MB memory