![]() |
idHTTP - GET mit Header und Kompression
Hallo zusammen,
ich habe bereits die ganze Nacht gegooglet und habe mit jetzt entschieden, DP beizutreten, da ich es ehrlich gesagt für das kompetenteste Forum halte bisher. Ich hoffe, ihr könnt mir helfen. Ich möchte gerne die ![]() ![]() Die API verlangt GET Abfragen, im Header "Accept-Encoding: gzip", und die Antwort kommt als gzip komprimiertes XML. Folgende Unit habe ich mir bisher dafür zusammengebastelt - leider ohne Erfolg, ich erhalte als Antwort immer "HTTP/1.1 200 OK"; die Bestätigung nützt mir aber nicht viel, ich möchte ja gerne an die Daten. Vorab-Info, damit ihr euch nicht allzusehr einlesen müsst: MakeURL erzeugt z. B. einen Link im Format
Code:
http://www.discogs.com/search?type=artists&q=metallica&f=xml&api_key=<API_Key>
Delphi-Quellcode:
Kann mir jemand helfen, wie ich an die XML-Daten komme, bzw. sagen, was ich falsch mache? Ich bin noch sehr unerfahren auf dem Gebiet HTTP Get und Post (sowie im Delphi-Umgang mit XML, aber das ist ja sekundär, es würde mir ja schon reichen, wenn ich das XML-Ergebnis zunächst mal als Fließtext sehe).
unit U_Discogs;
interface uses Classes, SysUtils, idHTTP, IdHTTPHeaderInfo, IdCompressorZLibEx; var Compressor: TIdCompressorZLibEx; DC_HTTP: TidHTTP; function DC_SearchArtist(Name: String): Boolean; implementation function MakeURL(SType, STerm: String): String; begin STerm:=StringReplace(LowerCase(STerm),' ','+',[rfReplaceAll]); result:='http://www.discogs.com/search?type='+SType+'q='+STerm+'&f=xml&api_key=<API_Key>'; end; function DC_SearchArtist(Name: String): Boolean; var Response: TStringStream; ResponseT: String; begin Response:=TStringStream.Create(''); try with DC_HTTP.Request do begin Method:='GET'; URL:=MakeURL('artists',Name); Host:='www.discogs.com'; AcceptEncoding:='gzip'; end; DC_HTTP.Get(MakeURL('artists',Name),Response); ResponseT:=Response.DataString; except on E: Exception do begin ResponseT:=''; end; end; Response.Free; result:=Pos('<resp stat="ok"',ResponseT)=1; end; initialization DC_HTTP:=TidHTTP.Create; Compressor:=TIdCompressorZLibEx.Create(DC_HTTP); DC_HTTP.Compressor:=Compressor; finalization Compressor.Free; DC_HTTP.Free; end. Liegt der Fehler darin, dass ich TStringStream nehme und nicht etwa eine XML Komponente aus xmldom, XMLIntf, msxmldom bzw. XMLDoc (ich verwende immer alle 4 gleichzeitig, weil ich nie weiß, was wo implementiert ist)? Ich hoffe, ihr könnt mir helfen. Übrigens: den API-Key kann ich euch natürlich leider nicht geben. Aber ich bin gerne bereit, eure Vorschläge jedes mal im Programm auszuprobieren. P.S.: Die Stichworte sind ja lustig, get ist zu allgemein, neue darf ich nicht verwenden, welche es schon gibt kann ich nicht einsehen. Sollte man vielleicht mal mit Vorschlägen versehen, damit man weiß, welche man verwenden darf. |
AW: idHTTP - GET mit Header und Kompression
Guten Morgen Chris, herzlich Willommen in der Delphi-PRAXiS!
Bei deiner Funktion prüfst du lediglich, ob <resp stat="ok" im XML-Code enthalten ist und gibst dessen Position zurück. Du möchtest jedoch den XML-Code erhalten. Das könnte z.B. so aussehen (letzte Zeile):
Delphi-Quellcode:
Ein möglicher Aufruf:
function DC_SearchArtist(Name: String): string;
var Response: TStringStream; ResponseT: String; begin Response := TStringStream.Create(''); try with DC_HTTP.Request do begin Method := 'GET'; URL := MakeURL('artists', Name); Host := 'www.discogs.com'; AcceptEncoding := 'gzip'; end; DC_HTTP.Get(MakeURL('artists', Name), Response); ResponseT := Response.DataString; except on E: Exception do begin ResponseT := ''; end; end; Response.Free; // XML-Code zurückgeben Result := ResponseT; end;
Delphi-Quellcode:
PS: Zu den Stichwirten im Forum:
// Evtl. mit der Kodierung wie z.B. UTF8 aufpassen. Je nach Delphi-Version muss hier noch
// Utf8Decode() oder Utf8ToString() o.ä. aufgerufen werden Memo1.Text := DC_SearchArtist('Beatles'); Wie haben vor Kurzem die Foren-Software gewechselt und da funktioniert noch nicht alles so, wie es soll, u.a. die Stichworte (wir kennen solche Fehlerchen als Programmierer nur zu gut ;) ). Aber das wird sich in absehbarer Zeit ändern. Grüße, Matze Nachtrag: Noch einen kleinen Fehler entfernt. Nachtrag 2: Ich sehe gerade, dass du nur die Zeilenumbrüche anpassen musst. Die Kodierung sollte bereits passen. |
AW: idHTTP - GET mit Header und Kompression
Zitat:
Hihi, schau nochmal genau hin :wink: Ich gebe nicht die Position zurück, sondern "true", wenn der Code mit <resp stat="ok" beginnt - demnach fungiert die Rückgabe als eine Erfolgsmeldung (oder eben nicht^^). Muss ich aber noch in
Delphi-Quellcode:
ändern, weil die Reihenfolge wohl doch nicht so festliegt, dass stat das erste Attribut ist.
result:=Pos(' stat="ok"',ResponseT)>0
Wichtiger jedoch: Wenn ich deinen Code übernehme klappt es mit der XML. :thumb: Wow, ich war also gar nicht so weit entfernt von der Lösung wie ich dachte - ich war schlicht und ergreifend zu dumm :stupid: Ich habe aus der anderen Unit auf DC_HTTP.ResponseText zugegriffen, statt auf die eigentliche Antwort... :oops: Achso, noch eine Frage: Kann ich statt
Delphi-Quellcode:
nicht eigentlich auch direkt
DC_HTTP.Get(MakeURL('artist', Name), Response); ResponseT := Response.DataString; result := ResponseT;
Delphi-Quellcode:
schreiben?
result := DC_HTTP.Get(MakeURL('artist', Name));
|
AW: idHTTP - GET mit Header und Kompression
Hallo Chris
Zitat:
Zitat:
Zitat:
Aber das kannst du auch ganz einfach selbst testen. |
AW: idHTTP - GET mit Header und Kompression
So, danke an Matze, betrachtet das Thema als erledigt (falls es hier so ein System gibt). Jedenfalls für alle anderen (ich hasse es, wenn jemand als letzten Beitrag schreibt "Geht jetzt, danke" aber dann nicht mehr genau wie eigentlich), die ein ähnliches Problem haben (werden - Google wird in Zukunft dann weiterhelfen können), hier nochmal abschließend meine gesamte Discogs Unit, für euch sogar, entgegen meinem üblichen Programmierstil für meine privaten Programme, kommentiert. :)
Delphi-Quellcode:
unit U_Discogs;
interface uses Classes, SysUtils, idHTTP, IdHTTPHeaderInfo, IdCompressorZLibEx, xmldom, XMLIntf, msxmldom, XMLDoc; var Compressor: TIdCompressorZLibEx; DC_HTTP: TidHTTP; DC_XML: TXMLDocument; function DC_SearchArtist(Name: String): Boolean; function DC_SearchRelease(Name: String): Boolean; // DC_SearchLabel könnte entsprechend hinzugefügt werden // Ich persönlich brauche es momentan aber nicht implementation function MakeURL(SType, STerm: String): String; begin STerm:=StringReplace(STerm,' ','+',[rfReplaceAll]); // Eventuell muss der Suchterm für die API später noch weiter angepasst werden, z. B. mit TIdURI.URLEncode result:='http://www.discogs.com/search?type='+SType+'s&q='+STerm+'&f=xml&api_key=<API_Key>'; // URL erzeugen end; // Allgemeine Suchfunktion für alle Typen (SType) function DC_SearchRequest(SType, Name: String): Boolean; var Response: TStringStream; begin Response := TStringStream.Create(''); try DC_HTTP.Get(MakeURL(SType, Name), Response); DC_XML.LoadFromStream(Response,xetUTF_8); // Zugriff auf Ergebnis bei erfolgreicher Suche später über DC_XML except on E: Exception do DC_XML.XML.Text:=''; end; Response.Free; result:=Pos(' stat="ok"',DC_XML.XML.Text)>0; // Erfolgsbestätigung end; // "Weiterleitungen" mit automatischem Suchparameter // Auf diese Weiterleitungen könnte auch verzichtet werden // Allerdings gibt es in meinem Projekt viele API-Units, die standardisierte function-Namen verwenden function DC_SearchArtist(Name: String): Boolean; begin result:=DC_SearchRequest('artist',Name); end; function DC_SearchRelease(Name: String): Boolean; begin result:=DC_SearchRequest('release',Name); end; // Label-Suche ggf. entsprechend mit 'label' einfügen // Die Zerlegung des Ergebnisses in meine TArtist, TAlbum und TSong-Klassen fehlt noch initialization DC_HTTP:=TidHTTP.Create; // Allgemeine TidHTTP Komponente der Discogs-Unit Compressor:=TIdCompressorZLibEx.Create(DC_HTTP); // Discogs sendet gzip komprimiert DC_HTTP.Compressor:=Compressor; DC_HTTP.Request.AcceptEncoding:='gzip'; // GET Header mit "Accept-Encoding: gzip" versehen DC_XML:=TXMLDocument.Create(''); // Allgemeine TXMLDocument Komponente der Discogs-Unit finalization // Beim Beenden die allgemeinen Objekte wieder freigeben DC_XML.Free; Compressor.Free; DC_HTTP.Free; end. |
AW: idHTTP - GET mit Header und Kompression
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz