AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi idHTTP - GET mit Header und Kompression
Thema durchsuchen
Ansicht
Themen-Optionen

idHTTP - GET mit Header und Kompression

Ein Thema von LWChris · begonnen am 27. Jul 2010 · letzter Beitrag vom 28. Jul 2010
Antwort Antwort
Benutzerbild von LWChris
LWChris

Registriert seit: 27. Jul 2010
Ort: Erkelenz
22 Beiträge
 
Turbo Delphi für Win32
 
#1

idHTTP - GET mit Header und Kompression

  Alt 27. Jul 2010, 05:01
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 Discogs API verwenden (API-Dokumentation falls jemand das Folgende selbst nachlesen will), um (für's erste einmal) Künstler nachzuschlagen.

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:
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.
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).

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.
Chris
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: idHTTP - GET mit Header und Kompression

  Alt 27. Jul 2010, 05:35
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:
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;
Ein möglicher Aufruf:
Delphi-Quellcode:
// 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');
PS: Zu den Stichwirten im Forum:
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.

Geändert von Matze (27. Jul 2010 um 05:43 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von LWChris
LWChris

Registriert seit: 27. Jul 2010
Ort: Erkelenz
22 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: idHTTP - GET mit Header und Kompression

  Alt 27. Jul 2010, 06:12
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.
Juhu Matze, danke für die Grüße.

Hihi, schau nochmal genau hin 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 result:=Pos(' stat="ok"',ResponseT)>0 ändern, weil die Reihenfolge wohl doch nicht so festliegt, dass stat das erste Attribut ist.

Wichtiger jedoch:
Wenn ich deinen Code übernehme klappt es mit der XML.

Wow, ich war also gar nicht so weit entfernt von der Lösung wie ich dachte - ich war schlicht und ergreifend zu dumm Ich habe aus der anderen Unit auf DC_HTTP.ResponseText zugegriffen, statt auf die eigentliche Antwort...


Achso, noch eine Frage:

Kann ich statt DC_HTTP.Get(MakeURL('artist', Name), Response); ResponseT := Response.DataString; result := ResponseT; nicht eigentlich auch direkt result := DC_HTTP.Get(MakeURL('artist', Name)); schreiben?
Chris
Software: schnell, effektiv, günstig. Wähle zwei.
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: idHTTP - GET mit Header und Kompression

  Alt 27. Jul 2010, 11:34
Hallo Chris

Hihi, schau nochmal genau hin Ich gebe nicht die Position zurück, sondern "true" [...]
Stimmt, das wollte ich eigentlich auch schreiben. Im Funktionskopf steht ja "Boolean". War wohl noch nicht ganz wach.

Wow, ich war also gar nicht so weit entfernt von der Lösung wie ich dachte
Jupp.

Achso, noch eine Frage:

Kann ich statt
Delphi-Quellcode:
DC_HTTP.Get(MakeURL('artist', Name), Response);
ResponseT := Response.DataString;
result := ResponseT;
nicht eigentlich auch direkt result := DC_HTTP.Get(MakeURL('artist', Name)); schreiben?
Ja, das geht. So mach ich's immer.
Aber das kannst du auch ganz einfach selbst testen.
  Mit Zitat antworten Zitat
Benutzerbild von LWChris
LWChris

Registriert seit: 27. Jul 2010
Ort: Erkelenz
22 Beiträge
 
Turbo Delphi für Win32
 
#5

AW: idHTTP - GET mit Header und Kompression

  Alt 28. Jul 2010, 13:09
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.
Chris
Software: schnell, effektiv, günstig. Wähle zwei.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: idHTTP - GET mit Header und Kompression

  Alt 28. Jul 2010, 13:11
Zitat:
für euch sogar, entgegen meinem üblichen Programmierstil für meine privaten Programme, kommentiert.
Sehr löblich
Markus Kinzler
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz