2017-07-06 4 views
0

Ich möchte mit dem Python 3-Modul urllib auf eine Elasticsearch-Datenbank unter localhost:9200 zugreifen. Mein Skript erhält eine gültige Anfrage (generiert von Kibana) an STDIN im JSON-Format. HierZugreifen auf Elasticsearch mit Python 3

ist das, was ich getan habe:

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() 

(Ich verstehe, dass meine repsonse.read() nicht viel Sinn für sich allein nicht, aber ich wollte es nur einfach halten.)

Als ich das Skript ausführen , erhalte ich eine

HTTP Error 400: Bad request 

ich bin sehr sicher, dass die JSON-Daten I Rohrleitung an das Skript bin richtig ist, da ich es gedruckt hatte, und fütterte es über curl zu Elast ich habe die Dokumente, die ich erwartet hatte, zurückbekommen.

Irgendwelche Ideen, wo ich falsch gelaufen bin? Benutze ich urllib richtig? Kann ich die JSON-Daten in der urlencode Zeile durcheinander bringen? Fragesuche ich Elasticsearch korrekt?

Danke für Ihre Hilfe.

+0

Sie müssen wahrscheinlich einen Inhaltstyp angeben ... siehe hier: https://docs.python.org/3/library/urllib.request.html#urllib.request.Request .. wenn Sie nicht angeben Bei einem Inhaltstyp wird standardmäßig "application/x-www-form-urlencoded" verwendet. Dies ist nicht das, was Sie gesendet haben. Wenn es Ihnen nichts ausmacht, eine externe Bibliothek zu verwenden, machen Anfragen (http://docs.python-requests.org/en/master/) dies ein wenig einfacher ... –

+0

Können Sie ein Beispiel für das Datenobjekt angeben, dass Sie gehen zu ElasticSearch? Btw Ich benutze die Anfragen-Bibliothek für die Abfrage an ES. Es ist super einfach. Nur neugierig - warum Kibana verwenden, um die Nutzlast (Daten) zu erstellen und was gedenken Sie mit der Antwort zu tun, sobald Sie die 400 überschreiten? – jlaur

+0

@CorleyBrigman: Ich wünschte, ich könnte die Anfrage-Bibliothek verwenden. Leider arbeite ich in einer Hochsicherheitsumgebung und sie sind sehr zurückhaltend, etwas mehr als das zu installieren, was unbedingt benötigt wird. – eins6180

Antwort

0

Mit Anfragen können Sie eines von zwei Dingen tun

1) Entweder man die Stringdarstellung des json erstellen Objekt selbst und es wie so abzuschicken:

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

2) Oder Sie haben Anfragen macht es für Sie so mögen:

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

also je nachdem, was aus dem sys.stdin Anruf tatsächlich kam (wahrscheinlich - wie Kibana wäre das Senden, dass, wenn das Ziel ist Elasticsearch - Eine String-Repräsentation eines JSON-Objekts == Entspricht der Ausführung von json.dumps in einem Dictionary), aber Sie müssen möglicherweise ein Bit abhängig von der Ausgabe von sys.stdin anpassen.

Meine Vermutung ist, dass der Code so von nur tun, funktionieren könnte:

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

Und wenn Sie dann mit ihm in Python einige Arbeit tun mögen, haben Anfragen einen für diese auch zur Unterstützung gebaut. Sie rufen diese:

json_response = response.json() 

Hoffnung, dies hilft Ihnen auf dem richtigen Weg. Für weitere Informationen om json.dumps/loads - this answer hat ein paar gute Sachen drauf.

+0

Danke! Wenn es mir nicht gelingt, mein Skript mit urllib zu arbeiten, werde ich versuchen, sie davon zu überzeugen, Anfragen zu installieren. Aber ich bin sehr skeptisch, dass sie diesem Vorschlag folgen werden. – eins6180

+0

Aaah. Sehen Sie sich diese SO-Frage an, wie Sie eine POST-Anfrage mit Json-Payload mit Hilfe von urllib durchführen können: https://Stackoverflow.com/a/4998300/8240959 und https://Stackoverflow.com/a/9746432/8240959 – jlaur

Verwandte Themen