Python无法通过HTTP获取简单的JSON对象,因为在获取JSON对象错误时无法连接'str'和'tuple'对象。但是,相同的脚本在具有相同设置(OS,python版本,python模块等)的不同机器上运行时没有任何问题。
使用的版本:python-2.6.6-52.el6.x86_64 操作系统:RHEL 6.6
脚本:
#!/usr/bin/env python
import requests
import json
def main():
f = requests.get("http://peslog001.abc.local:9200/_cluster/health")
health = f.json()
print health
if __name__ == "__main__":
main()
输出:
./gettest.py
Traceback (most recent call last):
File "./gettest.py", line 12, in <module>
main()
File "./gettest.py", line 7, in main
f = requests.get("http://peslog001.abc.local:9200/_cluster/health")
File "/usr/lib/python2.6/site-packages/requests/api.py", line 55, in get
return request('get', url, **kwargs)
File "/usr/lib/python2.6/site-packages/requests/api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.6/site-packages/requests/sessions.py", line 279, in request
resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
File "/usr/lib/python2.6/site-packages/requests/sessions.py", line 374, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.6/site-packages/requests/adapters.py", line 219, in send
r = self.build_response(request, resp)
File "/usr/lib/python2.6/site-packages/requests/adapters.py", line 96, in build_response
response.encoding = get_encoding_from_headers(response.headers)
File "/usr/lib/python2.6/site-packages/requests/utils.py", line 281, in get_encoding_from_headers
content_type, params = cgi.parse_header(content_type)
File "/usr/lib64/python2.6/cgi.py", line 310, in parse_header
parts = _parseparam(';' + line)
TypeError: cannot concatenate 'str' and 'tuple' objects
在第二台机器上输出相同的脚本:
./gettest.py
{u'status': u'green', u'number_of_nodes': 7, u'unassigned_shards': 0, u'timed_out': False, u'active_primary_shards': 1441, u'cluster_name': u'elasticsearch', u'relocating_shards': 0, u'active_shards': 2882, u'initializing_shards': 0, u'number_of_data_nodes': 4}
为什么会发生这种情况?
提前谢谢。
它从文件中读取确定,它似乎与从URL获得的响应有问题:
#!/usr/bin/env python
import requests
import json
def main():
f = open("/etc/zabbix/testjson").read()
health = json.loads(f)
print health
if __name__ == "__main__":
main()
输出:
# ./gettest2.py
{u'status': u'green', u'number_of_nodes': 7, u'unassigned_shards': 0, u'timed_out': False, u'active_primary_shards': 1441, u'cluster_name': u'elasticsearch', u'relocating_shards': 0, u'active_shards': 2882, u'initializing_shards': 0, u'number_of_data_nodes': 4}
使用CURL获取响应没有问题:
# curl http://peslog001.abc.local:9200/_cluster/health
{"cluster_name":"elasticsearch","status":"green","timed_out":false,"number_of_nodes":7,"number_of_data_nodes":4,"active_primary_shards":1441,"active_shards":2882,"relocating_shards":0,"initializing_shards":0,"unassigned_shards":0}
...
curl -s -D - -o /dev/null peslog001.abc.local:9200/_cluster/health
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 230
utils.py调试结果:
> /usr/lib/python2.6/site-packages/requests/utils.py(277)get_encoding_from_headers()
-> content_type = headers.get('content-type')
(Pdb) n
> /usr/lib/python2.6/site-packages/requests/utils.py(278)get_encoding_from_headers()
-> print content_type
(Pdb) n
('content-type', 'application/json; charset=UTF-8')
> /usr/lib/python2.6/site-packages/requests/utils.py(279)get_encoding_from_headers()
-> if not content_type:
(Pdb)
> /usr/lib/python2.6/site-packages/requests/utils.py(282)get_encoding_from_headers()
-> content_type, params = cgi.parse_header(content_type)
(Pdb)
TypeError: "cannot concatenate 'str' and 'tuple' objects"
在脚本工作的服务器上输出调试显示content_type不同:
> /usr/lib/python2.6/site-packages/requests/utils.py(277)get_encoding_from_headers()
-> content_type = headers.get('content-type')
(Pdb) n
> /usr/lib/python2.6/site-packages/requests/utils.py(278)get_encoding_from_headers()
-> print content_type
(Pdb) n
application/json; charset=UTF-8
> /usr/lib/python2.6/site-packages/requests/utils.py(279)get_encoding_from_headers()
-> if not content_type:
(Pdb) n
> /usr/lib/python2.6/site-packages/requests/utils.py(282)get_encoding_from_headers()
-> content_type, params = cgi.parse_header(content_type)
(Pdb) n
解决方法(非常糟糕的一个,但我没有使用phyton用于其他任何事情,所以我可以忍受它):
将以下行添加到utils.py get_encoding_from_headers()
content_type = "application/json; charset=UTF-8"