Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co. (https://www.delphipraxis.net/111148-umlaute-problem-mit-idhttp-get-indy-%3D-%E3%B6-und-co.html)

MCXSC 30. Mär 2008 16:50


Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Hallo,

ich habe folgenden Code:

Delphi-Quellcode:
var
  HTMLCode: TStringList;

[...]

function DownloadHTML(URL: String): String;
begin
  try
    Result := IndyHTTP.Get(URL);
  except
    Exit;
  end;
  Result := StringReplace(Result, #13, #13#10, [rfReplaceAll]);
end;
Damit lese ich also den HTML-Code einer URL aus. Jedoch habe ich das Problem, dass bei manchen Webseiten nur z.B. folgendes herauskommt:

Zitat:

Doch Elben und Menschen verbündeten sich und konnten Sauron schließlich bezwingen. Doch der Ring wurde nicht zerstört, sondern ging verloren, weswegen auch Sauron nicht vollständig besiegt wurde. Nach Hunderten von Jahren geriet der Ring in die Hände des Hobbits Bilbo Beutlin (Ian Holm), der an ihm nur die Fähigkeit nutzte, sich damit unsichtbar machen zu können. Doch als der Ring an seinen Neffen Frodo (Elijah Wood) übergeht, erahnt der Zauberer Gandalf (Ian McKellen), um was es sich bei dem Schmuckstück handelt. Da die finsteren neun Ringgeister, schwarze Reiter, bereits nach dem Ring Ausschau halten, rät Gandalf Frodo, den Ring in das Elbenheim Bruchtal zu bringen, wo über sein weiteres Schicksal entschieden werden soll. Also macht sich Frodo mit seinen Gefährten Sam (Sean Astin), Merry und Pippin auf die gefahrvolle Reise, auf der sie von dem geheimnisvollen Waldläufer Streicher (Viggo Mortensen) Hilfe finden. Doch das ist er der Auftakt zu einem großen Abenteuer, das zur Gründung der neunköpfigen Gemeinschaft des Rings führt, einer Abordnung, die Saurons Fluch zerstören soll...
Wie man sieht, "funktionieren" die Umlaute nicht korrekt. Das Problem tritt aber nicht bei allen URLs auf, sondern nur bei manchen (aber alles deutsche URLs).

Ich habe bisher keine Fehlerlösung gefunden... Hat hier vielleicht jemand eine Idee?

Have fun,
MCXSC

marabu 30. Mär 2008 16:53

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Hallo Marcel,

nicht alle HTML-Seiten werden gleich passend im Windows ANSI Code ausgeliefert (CP1252). Probiere es mal so:

Delphi-Quellcode:
// ...
    Result := Utf8ToAnsi(IndyHTTP.Get(URL));
// ...
Grüße vom marabu

Bernhard Geyer 30. Mär 2008 18:49

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von MCXSC
Ich habe bisher keine Fehlerlösung gefunden... Hat hier vielleicht jemand eine Idee?

Funktioniert doch. Die Dateien sind "nur" UTF8-Codiert und ist damit (wenn der Text in einer HTML-Datei verwendet wird und die Codierung korrekt angegebn ist) auch 100% in Ordnung.

MrKnogge 30. Mär 2008 19:05

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Muss man hier vor dem Aufruf von Utf8ToAnsi überprüfen, ob es utf8 kodiert ist, oder kann man bedenkenlos alles an die Funktion übergeben ?

marabu 30. Mär 2008 19:17

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Hallo Christian,

es liegt in der Natur der Sache, dass ein AnsiString stets beides enthalten kann. Die Erkennung der UTF-8 Lead-Bytes ist genau die Spezialität der Ansi-Funktionen - und auch Utf8ToAnsi() beherrscht das gut.

Freundliche Grüße

phXql 30. Mär 2008 19:40

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Wenn sie denn der Webserver ausliefert. Afaik kann der Internet Explorer nicht mit den BOMs umgehen.

Bernhard Geyer 30. Mär 2008 19:58

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von phXql
Wenn sie denn der Webserver ausliefert. Afaik kann der Internet Explorer nicht mit den BOMs umgehen.

Der Browser wird primär die Codierungsinformationen des HTTP-Response auswerten und danach die der HTML-Datei. AFAIK kommt er auch mit dem BOM zurecht, ignoriert ihn aber u.U.

MCXSC 30. Mär 2008 20:11

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von marabu
Delphi-Quellcode:
// ...
    Result := Utf8ToAnsi(IndyHTTP.Get(URL));
// ...

Danke, aber wenn ich das so mache, bekomme ich im weiteren Verlauf immer ein "Listenindex überschreitet das Maximum (-1)", da der String/die Stringlist anscheinend immer leer ist?

MrKnogge 30. Mär 2008 20:30

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Du hast oben zwar eine Stringlist deklariert, aber benutzt keine, zumindest nicht in dem Code den du gepostest hast.

Bernhard Geyer 30. Mär 2008 20:51

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Liste der Anhänge anzeigen (Anzahl: 1)
[Off-Topic]Thunderbird hat wohl etwas zu viel Automatismus bezüglich übereiliger UTF8-Decodierung eingebaut[/Off-Topic]

MCXSC 30. Mär 2008 20:53

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Doch ich benutze sie... Mal ein wenig mehr Code:

Delphi-Quellcode:
var
  HTMLCode: TStringList;

function DownloadHTML(URL: String): String;
begin
  try
    Result := UTF8ToANSI(HTTP.Get(URL));
  except
    Exit;
  end;
  Result := StringReplace(Result, #13, #13#10, [rfReplaceAll]);
end;

function BearbeiteHTML(HTML: TSTringList): String;
begin
  //...
end;

procedure Suchen(MyString: String;);
begin
  HTMLCode := TStringList.Create;
  Dothisandthis(Filmtitel);
  FreeAndNil(HTMLCode);
end;

procedure Dothisandthis(MyString: String);
var
  i: Integer;
begin
  HTMLCode.Text := DownloadHTML('http://www.domain.url');
  HTMLCode.Text := BearbeiteHTML(HTMLCode);
  if Pos('[i]XXX[/i]', HTMLCode.Text) <> 0 then Exit
  else begin
    //...
  end;
end;
Zwar ein bisschen gekürzt, aber das wichtige ist drin.

Der Compiler gibt ab dem "if Pos('XXX', HTMLCode.Text) <> 0 then Exit" den oben genannten Fehler aus.

Zitat:

Zitat von Bernhard Geyer
[Off-Topic]Thunderbird hat wohl etwas zu viel Automatismus bezüglich übereiliger UTF8-Decodierung eingebaut[/Off-Topic]

Ist mir grade ebend auch aufgefallen... :)

Bernhard Geyer 30. Mär 2008 20:58

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Wieso benutzt du nicht den TWebBrowser und MSHTML und damit IHTMLDocument und gehst durch all deine gewünschten Elemente? IE + MSHTML nimmt dir doch das ganze Charset/Codierung sowie die m.E. unpassenden POS-Aufrufe für ein Dokumentenformat ab für welches man viel einfacher über den DOM eines dafür entwickelten Komponente geht.

MCXSC 30. Mär 2008 21:01

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von Bernhard Geyer
Wieso benutzt du nicht den TWebBrowser und MSHTML und damit IHTMLDocument und gehst durch all deine gewünschten Elemente? IE + MSHTML nimmt dir doch das ganze Charset/Codierung sowie die m.E. unpassenden POS-Aufrufe für ein Dokumentenformat ab für welches man viel einfacher über den DOM eines dafür entwickelten Komponente geht.

Eben nicht. Ich brauche halt nur den Code in einer StringList, dieser wird später weiterverarbeitet, bzw. es werden Dinge ausgelesen. Der TWebBrowser wäre da ein komplett falscher Weg.

MrKnogge 30. Mär 2008 21:09

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Bist du dir sicher, dass der Fehler in der Zeile "if Pos('XXX', HTMLCode.Text) <> 0 then Exit" ist, was steht denn in HTMLCode.Text drinnen ?

Greifst du denn in dem else-zweig auf HTMLCode zu ?

MCXSC 30. Mär 2008 21:11

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Ich teste grade, aber bis dahin kommt der Compiler eben (habe da auch mal nen Haltepunkt) gesetzt.

Und speichern kann ich die StringList eben auch (vorher) [HTMLCode.SaveToFile('dateiname.txt')], und der Inhalt ist halt so, wie er sein soll, aber immer noch mit dem Umlautproblem.

Und ja: Später wird noch auf die HTMLCode zurückgegriffen.

//Edit: Mal davon abgesehen, scheint UTF8toANS() hier nicht zu greifen...

Bernhard Geyer 30. Mär 2008 21:45

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von MCXSC
Eben nicht. Ich brauche halt nur den Code in einer StringList, dieser wird später weiterverarbeitet, bzw. es werden Dinge ausgelesen. Der TWebBrowser wäre da ein komplett falscher Weg.

Und? Wenn du den DOM vom TWebbrowser aufbauen lässt und solche dinge wie [i]-Elemente auslesen willst ist das sehr einfach möglich in dem du dem IHTMLDocument sagst das du alle entsprechende Elemente haben willst. Läßt sich in ca. 10 Zeilen Quellcode realisieren.

MCXSC 30. Mär 2008 21:57

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Nein, ich lese kein [i]-Element aus. Okay, da du wohl einen Grund brauchst, gebe ich dir einen (auch wenn es nichts zur Sache tut):

Wenn die Zeile "XXX" in dem Code vorkommt (oder im Original: "Keine Ergebnisse") soll eine MessageBox ausgegeben werden (im kurzen Ausschnitt eben "exit"). Werden allerdings Ergebnisse gefunden, so geht es weiter. Dann wird der obere HTML-Code weggeschnitten und es wird nach z.B. "<td>Genre:</td>" gesucht und weiter ausgelesen. Sprich: Es ist ein Teil der HTML-Auslesefunktion von myCine. Das was du mir da also erzählst, ist (was diesen Fall betrifft) unbrauchbar. ;)

MrKnogge 30. Mär 2008 22:08

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Wenn er welche findet, liefert dir pos aber <> 0 zurück und geht raus :wink:

MCXSC 30. Mär 2008 22:14

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von MrKnogge
Wenn er welche findet, liefert dir pos aber <> 0 zurück und geht raus :wink:

Nein. Pos liefert mir "0" zurück, wenn er keine findet (dann eben Exit bzw. eine Messagebox). Wenn nicht geht es im else-Teil weiter. Aber ich verstehe nicht, was das zur Sache tut? Er liest ja alle (in diesem Falle) Filmdaten aus, nur eben werden die Umlaute falsch angezeigt. ;)

Bernhard Geyer 30. Mär 2008 22:18

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von MCXSC
Nein, ich lese kein [i]-Element aus. Okay, da du wohl einen Grund brauchst, gebe ich dir einen (auch wenn es nichts zur Sache tut):

Wenn die Zeile "XXX" in dem Code vorkommt (oder im Original: "Keine Ergebnisse") soll eine MessageBox ausgegeben werden

:gruebel: Versteh ich jetzt nicht? Du suchst jetzt doch [i]-Elemente, oder doch nicht?

Zitat:

Zitat von MCXSC
... und es wird nach z.B. "<td>Genre:</td>" gesucht und weiter ausgelesen. Das was du mir da also erzählst, ist (was diesen Fall betrifft) unbrauchbar. ;)

Du werkelst doch ziemlich auf dem DOM des HTML-Dokumentes herum. Wieso sollte dann MSHTML und IHTMLDocument nicht brauchbar sein?


Übrigens. Das Design deiner Seite ist ja ziemlich Hip. :thumb:

MCXSC 30. Mär 2008 22:26

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von Bernhard Geyer
:gruebel: Versteh ich jetzt nicht? Du suchst jetzt doch [i]-Elemente, oder doch nicht?

Ich suche nicht nach dem [i]-Element, sondern eher nach "Keine Ergebnisse". Das ich das [i]-Element noch mitsuche, hängt nur damit zusammen, dass es das einzige ist, es gibt sonst mehrere "Keine Ergebnisse". Ist ein wenig schwer zu erkären, aber damit du von deinem Element-Gesuche gedanklich wegkommst: Ich suche nur nach "Keine Ergebnisse".

Zitat:

Zitat von Bernhard Geyer
Du werkelst doch ziemlich auf dem DOM des HTML-Dokumentes herum. Wieso sollte dann MSHTML und IHTMLDocument nicht brauchbar sein?

Nicht nur. Es war Zufall, dass mir jetzt wieder ein Element einfiel. Aber es wird z.B. auch nach "http://www.domain.de/weitereinfos.php?..." gesucht; ich lese eben die Daten der OFDb aus, und brauche, um die entsprechenden Daten zu finden, eben anhaltspunkte.

Zitat:

Zitat von Bernhard Geyer
Übrigens. Das Design deiner Seite ist ja ziemlich Hip.

Sofern das "Hip" positiv gemeint ist: Danke. ;)

MrKnogge 30. Mär 2008 22:39

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von MCXSC
Nein. Pos liefert mir "0" zurück, wenn er keine findet (dann eben Exit bzw. eine Messagebox).

hier machst du aber etwas anderes:
Delphi-Quellcode:
if Pos('[i]XXX[/i]', HTMLCode.Text) <> 0 then Exit
dann muss es schon "= 0" heisen.

MCXSC 30. Mär 2008 22:44

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von MrKnogge
hier machst du aber etwas anderes:
Delphi-Quellcode:
if Pos('[i]XXX[/i]', HTMLCode.Text) <> 0 then Exit
dann muss es schon "= 0" heisen.

Wah, gut gut. Ich hab jetzt (während meiner Arbeit am Programm) kurz falsch rum gedacht. ;) So wäre es aber richtig:

Delphi-Quellcode:
begin
  HTMLCode.Text := DownloadHTML('http://www.domain.de...');
  if Pos('[i]Keine Ergebnisse[/i]', HTMLCode.Text) <> 0 then ShowMessage('Es wurde kein Film auf OFDb.de gefunden!')
  else begin
    //...
  end;
end;

MrKnogge 30. Mär 2008 22:51

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Alles klar, ok.

Aber wenn ein Listenindex das Maximum überschreitet, geht das imho nu, wenn man eben auch per index sich was aus der Stringlist rausfischt. Der Fehler kann also eigentlich nur in Zusammenhang mit HTMLCode[i] auftreten.

MCXSC 30. Mär 2008 22:57

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Ja, das stimmt. Ich weiß nun auch, wo der Fehler liegt oder eher lag:

Wenn UTF8toANSI nichts zu tun hat, so liefert es einen leeren String zurück. Da die Funktion bei der Übergabe von HTMLCode.Text wohl nur die erste Zeile "gescannt" hat (also HTMLCode[0]), und ab HTMLCode[1] nichts mehr gemacht hat, war eben dieses leer.

Ich habe es nun in etwa so gelöst, dass ich eine neue StringList erstellt habe, und jede Zeile von HTMLCode einzelnd durchlaufe und umwandel lasse, und diese Zeilen eben in der neuen Stringlist zusammensetzen lasse.

Ferdy2003 30. Mär 2008 23:49

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Hi,

mit PHP löse ich so ein Problem wie folgt:

$bad_char=array("ä","ö","ü","Ä","Ö","Ü","ß" );
$right=array('ä','ö','ü','Ä','Ö','Ü','ß');
$text=str_replace($bad_char,$right,$row["beschreibung"]);
$text = htmlentities($text);

d.h. ich ersetze in dem String einfach die falschen ($bad_char) durch die richtigen ($right) ich denke das ist auch mit Delphi möglich.

MCXSC 30. Mär 2008 23:57

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von Ferdy2003
mit PHP löse ich so ein Problem wie folgt:

$bad_char=array("ä","ö","ü","Ä","Ö","Ü","ß" );
$right=array('ä','ö','ü','Ä','Ö','Ü','ß');
$text=str_replace($bad_char,$right,$row["beschreibung"]);
$text = htmlentities($text);

d.h. ich ersetze in dem String einfach die falschen ($bad_char) durch die richtigen ($right) ich denke das ist auch mit Delphi möglich.

Es gibt nur für z.B. "ö" min. 2 Versionen - an die Idee hatte ich anfangs auch gedacht, aber ist eben (auch in PHP) unschön. Aber mit UTF8toAnsi hatte ich ja Erfolg - man muss dabei nur beachten, dass die Funktionen einen leeren String zurückgibt, wenn der String kein UTF8 ist.

marabu 31. Mär 2008 07:18

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Moin,

Zitat:

Zitat von MCXSC
... Es gibt nur für z.B. "ö" min. 2 Versionen ... Aber mit UTF8toAnsi hatte ich ja Erfolg - man muss dabei nur beachten, dass die Funktionen einen leeren String zurückgibt, wenn der String kein UTF8 ist.

das solltest du nochmal ganz in Ruhe prüfen.

Und was das Analysieren von markup angeht: Jeder Text gehorcht einer mehr oder weniger komplexen Grammatik - und wenn es bereits einen Parser für die Grammatik gibt, dann bist du einfach nur gut beraten, wenn du ihn auch benutzt. Zugegeben, die OFDb-Seite ist kaum für eine programmgesteuerte Online-Abfrage geeignet, aber mit der richtigen Technik lässt sich da schon etwas machen - auch im Hinblick auf das nächste Redesign der web site, was ja bestimmt nicht ganz ausgeschlossen werden kann.

Nachdenkliche Grüße

Bernhard Geyer 31. Mär 2008 07:35

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von MCXSC
Es gibt nur für z.B. "ö" min. 2 Versionen

ö als benanntes Zeichen?
MSHTML (oder auch ein anderer HTML-Parser) würde dir auch dies abnehmen.

MCXSC 31. Mär 2008 20:45

Re: Umlaute-Problem mit idHTTP.Get (Indy) => ö und Co.
 
Zitat:

Zitat von Bernhard Geyer
Zitat:

Zitat von MCXSC
Es gibt nur für z.B. "ö" min. 2 Versionen

ö als benanntes Zeichen?
MSHTML (oder auch ein anderer HTML-Parser) würde dir auch dies abnehmen.

Nochmals: Ich brauche KEINEN HTML-Parser, da dieser mir nicht Daten ausgeben kann. Jedenfalls nicht so, wie ich es brauche. Wenn irgendwo z.B. steht "Genre: xxx, yyy", dann parst er das nicht so, dass ich es einfach ausschneiden kann. Und das was du meinst ist kein UTF8.

Zitat:

Zitat von marabu
Zitat:

Zitat von MCXSC
... Es gibt nur für z.B. "ö" min. 2 Versionen ... Aber mit UTF8toAnsi hatte ich ja Erfolg - man muss dabei nur beachten, dass die Funktionen einen leeren String zurückgibt, wenn der String kein UTF8 ist.

das solltest du nochmal ganz in Ruhe prüfen.

Hmm, okay, da hatte ich mich wohl verschaut. Aber gut, denke mal (wie du sagtest?), ist das UTF8toAnsi sowieso besser, da schon vorhanden. Und es klappt ja. :)

Zitat:

Zitat von marabu
Zugegeben, die OFDb-Seite ist kaum für eine programmgesteuerte Online-Abfrage geeignet, aber mit der richtigen Technik lässt sich da schon etwas machen - auch im Hinblick auf das nächste Redesign der web site, was ja bestimmt nicht ganz ausgeschlossen werden kann.

Najoa, aber eine Abfrage funktioniert ja. :) Was für eine Technik meinst du denn? OFDb bietet weder einen Zugang zur Datenbank, noch eine API o.ä., es bleibt also nur der HTML-Code.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:31 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