2017-07-06 56 views
0

我想使用Python 3模块urlliblocalhost:9200来访问数据库Elasticsearch。我的脚本得到一个有效的请求(由Kibana生成)以JSON格式传递给STDIN。访问Elasticsearch与Python 3

这里是我做过什么:

import json 
import sys 
import urllib.parse 
import urllib.request 

er = json.load(sys.stdin) 
data = urllib.parse.urlencode(er) 
data = data.encode('ascii') 
uri = urllib.request.Request('http://localhost:9200/_search', data) 
with urllib.request.urlopen(uri) as repsonse: 
    response.read() 

(据我所知,我的repsonse.read()本身并不多大意义,但我只是想保持简单。)

当我执行该脚本,我得到一个

HTTP Error 400: Bad request 

我非常肯定的JSON数据,我管的脚本是正确的,因为我把它印,并通过curl它喂给ELAST icsearch,并收回了我期望回来的文件。

任何想法,我哪里出错了?我正确使用urllib吗?我是否可能搞乱了urlencode系列中的JSON数据?我是否正确查询Elasticsearch?

感谢您的帮助。

+0

你可能需要指定的内容类型...在这里看到:https://docs.python.org/3/library/urllib.request.html#urllib.request.Request ..如果你不指定一个内容类型,它将默认为application/x-www-form-urlencoded,这不是你发送的内容。如果您不介意使用外部库,请求(http://docs.python-requests.org/en/master/)使这更简单一些... –

+0

您可以提供数据对象的示例吗?你传递给ElasticSearch?顺便说一句我使用请求库查询到ES。这非常简单。只是好奇 - 为什么使用Kibana来创建有效载荷(数据),并且一旦你通过了400,你打算如何处理这个响应? – jlaur

+0

@CorleyBrigman:我希望我可以使用请求库。不幸的是,我在高度安全的环境中工作,他们非常不愿意安装任何超出严格要求的东西。 – eins6180

回答

0

随着请求你可以做两件事情

1)要么你创建的JSON字符串表示反对自己,并把它关闭,像这样一个:

payload = {'param': 'value'} 
response = requests.post(url, data=json.dumps(payload)) 

2)或者你有要求为你做它像这样:

payload = {'param': 'value'} 
response = requests.post(url, json = payload) 

所以这取决于究竟是什么出来的sys.stdin呼叫(可能的 - 作为Kibana将发送,如果目标是ElasticSearch - 一个json对象的字符串表示,相当于在字典上执行json.dumps),但您可能需要根据sys.stdin的输出进行调整。

我的猜测是,你的代码可以通过只是在做这样的工作:

import sys 
import requests 
payload = sys.stdin 
response = requests.post('http://localhost:9200/_search', data=payload) 

如果你再想要做在Python用了一些工作,要求有一个内置的这种支持也。你只是这样称呼:

json_response = response.json() 

希望这可以帮助你走上正确的轨道。为进一步阅读om json.dumps/loads - this answer有一些好东西在上面。

+0

谢谢!如果我无法使用urllib处理脚本,我会尝试说服他们安装请求。但我非常怀疑他们会遵循这个建议。 – eins6180

+0

Aaah。看看这个SO问题如何使用urllib然后使用json有效内容执行POST请求:https://stackoverflow.com/a/4998300/8240959以及这一个https://stackoverflow.com/a/9746432/8240959 – jlaur