![]() |
Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Mit dem folgenden Code lese ich den HTML Code der geladenen Web-Seiten auf:
Code:
Damit der HTML Code der aufgerufenen Seiten vollständig als Text angezeigt werden kann muss ich ein MemoryStream nutzen, dazu habe ich schon in einem anderen Beitrag das Problem erläutert.
function GetHTMLCode(xUrl: String): String;
var xResult : TStringList; xResMemo : TMemoStream; begin xResult := TStringList.Create; xResMemo : TMemoStream.Create; try try IdHTTP1.Get(xUrl, xResMemo); xResMemo.Position := 0; xResult.Text := StreamToText(xResMemo, ' ', 00); except on E: EIdHTTPProtocolException do begin xResult.Add('E.Message: ' + E.Message); xResult.Add('E.ErrorMessage:'); xResult.Add(E.ErrorMessage); end; end; finally Result := xResult.Text; xResult.Free; xResMemo.Free; end; end; function StreamToText(sStream: TStream; sNewSign: string; sOldSign: Integer): AnsiString; var xLen, j, xSize : Integer; xTemp : string; begin try xLen := sStream.Size; SetLength(Result, xLen); if xLen > 0 then begin sStream.ReadBuffer(Result[1], xLen); for j := 1 to xLen do begin if Ord(Result[j]) = sOldSign then begin xTemp := xTemp + sNewSign end else begin xTemp := xTemp + Result[j]; end; end; end; finally Result := xTemp; end; end; Allerdings habe ich jetzt das Problem das kyrillische, chinesische, usw. Zeichen als Hieroglyphen angezeigt werden. Wie kann man die Zeichen aus der Funktion richtig in einen Text kodieren? |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Du greifst auf Result zu?
|
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Ich schätze fast ein TStringstream mit dem richtigen Encoding macht einerseits deine StreamToText procedure überflüssig und würde wahrscheinlich das richtige Ergebnis liefern.
Zitat:
sStream.ReadBuffer(Result[1], xLen); schreibt Daten in Result, falls das die Frage war. |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Welches Encoding wird verwendet (UTF-8, UTF-16, ...)?
|
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Zitat:
Allerdings scheint die Seite mit einem speziellen Content-Encoding geliefert zu werden (im Browser-Debugger von Firefox wird dies angezeigt): Content-Encoding: br Indy unterstützt dieses Encoding anscheinend nicht (Brotli). |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Zitat:
|
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Zitat:
|
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Zitat:
Dir ist klar, dass der Beitrag den ich gerade von dir zitiere #7 ist? Meiner wird #8 sein. #9+ existieren (noch) nicht.. |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
So hier meinte ich, nur grob hier hin gekritzelt, ich hoffe das klappt.
Delphi-Quellcode:
Function MyFilter ( inStream: TStream ): AnsiString;
var xBuf: TBytes; i : Integer; begin try SetLength(xBuf, inStream.Size); // puffer größe bestimmen inStream.ReadBuffer(Pointer(xBuf)^, Length(xBuf)); // puffer füllen for I := 0 to Length(xBuf) -1 do if xBuf[i] = 0 then xBuf[i] := 20; // mache aus 0 ein Leerzeichen finally SetLength(Result, Length(xBuf)); // ausgabegröße for I := 0 to Length(xBuf) -1 do Result[i+1] := AnsiChar(xBuf[i]); // alles aus puffer ins Result end; end; |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Also so funktionierts bei mir.
Damit kann ich ![]()
Delphi-Quellcode:
function TForm1.GetHTMLCode(xUrl: String): String;
var xResMemo : TStringStream; begin xResMemo := TStringStream.Create('', TEncoding.UTF8); try IdHTTP1.Get(xUrl, xResMemo); xResMemo.Position := 0; Result := xResMemo.DataString finally xResMemo.Free; end; end; |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Zitat:
"dazu habe ich schon in einem anderen Beitrag das Problem erläutert." -> Post #10 aus dem anderen Beitrag (von gestern, weiter unten) enthält die URL einer Warez-Seite, und diese verwendet das Content-Encoding "br" |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Vielen Dank schon mal für die zahlreichen Antworten.
KodeZwerg: Mit deinem Code werden leider bei mir die kyrillischen Zeichen immer noch als Hieroglyphen angezeigt. Getestet habe ich es mit der folgenden Seite: mail.ru. Neutral General: Ich kann leider TStringStream nicht nutzen, da ich sonst den HTML Code bestimmter Seiten als Text nicht komplett angezeigt bekomme. |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Zitat:
Welche Seite denn? Und welche Delphi-Version benutzt du? |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Wegen der unvollständigen Anzeige des HTML Codes, habe ich das Problem in diesem Thema erläutert:
![]() |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Auf dieser "dubiosen" Seite wurden heute weitere Beiträge hinzgefügt, somit hat sich der unvollständige HTML Code auf die Seite 37 verschoben:
![]() |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Stell doch mal dein komplettes Projekt (Source) ohne kompilierung gepackt als .zip/.rar Anhang rein, kann ja nicht groß sein, vielleicht liegt der Fehler an ganz anderer Stelle.
|
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Code:
unit Unit1;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdHTTP, Vcl.StdCtrls, Vcl.ExtCtrls, IdZLibCompressorBase, IdCompressorZLib, IdCookieManager, IdBaseComponent, IdComponent, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdSSLOpenSSLHeaders, IdCTypes; type TForm1 = class(TForm) Panel1: TPanel; Memo1: TMemo; Edit1: TEdit; Button1: TButton; IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL; IdCookieManager1: TIdCookieManager; IdCompressorZLib1: TIdCompressorZLib; procedure Button1Click(Sender: TObject); procedure IdSSLIOHandlerSocketOpenSSL1StatusInfoEx(ASender: TObject; const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType, AMsg: string); private { Private-Deklarationen } public { Public-Deklarationen } procedure SetNewIdHTTP; end; var Form1: TForm1; gIdHTTP : TIdHTTP; implementation {$R *.dfm} procedure TForm1.IdSSLIOHandlerSocketOpenSSL1StatusInfoEx(ASender: TObject; const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType, AMsg: string); begin SSL_set_tlsext_host_name(AsslSocket, gIdHTTP.Request.Host); end; procedure TForm1.SetNewIdHTTP; begin if Assigned(gIdHTTP) then begin Memo1.Clear; gIdHTTP.Free; end; gIdHTTP := TIdHTTP.Create(nil); gIdHTTP.AllowCookies := True; gIdHTTP.HandleRedirects := True; gIdHTTP.IOHandler := IdSSLIOHandlerSocketOpenSSL1; gIdHTTP.CookieManager := IdCookieManager1; gIdHTTP.Compressor := IdCompressorZLib1; end; function StreamToText(sStream: TStream; sOldSign, sNewSign: Integer): AnsiString; var xBuf: TBytes; i : Integer; begin try SetLength(xBuf, sStream.Size); // puffer größe bestimmen sStream.ReadBuffer(Pointer(xBuf)^, Length(xBuf)); // puffer füllen for I := 0 to Length(xBuf) -1 do if xBuf[i] = sOldSign then xBuf[i] := sNewSign; // mache aus 0 ein Leerzeichen finally SetLength(Result, Length(xBuf)); // ausgabegröße for I := 0 to Length(xBuf) -1 do Result[i+1] := AnsiChar(xBuf[i]); // alles aus puffer ins Result end; end; function IdHTTP_Get(sHTTP: TIdHTTP; sURL: String): String; var xResult : TStringList; xMemoRes : TMemoryStream; begin xResult := TStringList.Create; xMemoRes := TMemoryStream.Create; try try sHTTP.Get(sURL, xMemoRes); xMemoRes.Position := 0; xResult.Text := StreamToText(xMemoRes, 0, 20); except on E: EIdHTTPProtocolException do begin xResult.Add('E.Message: ' + E.Message); xResult.Add('E.ErrorMessage:'); xResult.Add(E.ErrorMessage); end; end; finally Result := xResult.Text; xResult.Free; xMemoRes.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); begin SetNewIdHTTP; Memo1.Text := IdHTTP_Get(gIdHTTP, Edit1.Text); end; end. |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Hallo bogdan,
gut wäre ein Projekt-Upload gewesen für alle Properties (die stehen in der .dfm Datei) die Du so gesetzt hast. Auch gut zu Wissen was in Edit1.Text steht, nur eine blanko Webadresse ohne Endung? Soll das Ziel sein den HTML Source-Code zu laden oder eine bestimmte Datei? edit Hier ein Beispiel um HTTP HTML Sourcecode zu laden:
Delphi-Quellcode:
Alles noch unoptimiert aber vielleicht ist es ja das was Du wolltest?
function DownloadHTMLSource( var xUrl : ansiString ):ansiString;
const INET_USERAGENT = 'Mozilla/4.0, Indy Library (Windows; en-US)'; // Damit sagst Du "Hallo, ich bin..." INET_TIMEOUT_SECS = 3; // Wieviele Sekunden warten bevor Timeout kommt? INET_REDIRECT_MAX = 10; // Maximale Redirect-Tiefe begin with tIdHttp.create(nil) do begin // Create Indy http object request.userAgent := INET_USERAGENT; // Custom user agent string redirectMaximum := INET_REDIRECT_MAX; // Maximum redirects handleRedirects := INET_REDIRECT_MAX<>0; // Handle redirects readTimeOut := INET_TIMEOUT_SECS*1000; // Read timeout msec try // Catch errors Result := Get(xUrl); // Do the request if URL.Port = '80' then URL.Port := ''; // Remove port 80 from final URL xUrl := URL.GetFullURI // Return final URL <<- da könnte nun eine andere URL stehen als wie Du eingegeben hast except // Return an error message if failed on E: Exception do Result := 'Error! HTTP Adress: ' +xUrl+ #13#10 + 'E.Message: ' + E.Message; // Return Error Message end; free // Free the http object end end; procedure TForm1.Button1Click(Sender: TObject); var temp1, temp2: ansiString; i : Integer; begin Memo1.Clear; Memo1.Lines.Add('Working...'); Temp1 := Edit1.Text; if Length(Edit1.Text) > 0 then Temp2 := DownloadHTMLSource(Temp1); // hier noch irgendwas mit ansiString anstellen, zum Beispiel nullen entfernen for I := 1 to Length(Temp2) do if Temp2[i] = Char(Ord($00)) then Temp2[i] := Char(Ord($20)); Memo1.Lines.Text := Temp2; Memo1.Lines.Add('HTTP HTML Source from: '+Temp1); end; Viel Spass damit. Ps: Diesen Code solltest Du in einem leeren Projekt testen ohne Indy Komponenten aufm Formular aber in Uses. |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Zitat:
|
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Zitat:
|
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Liste der Anhänge anzeigen (Anzahl: 1)
Siehe Bild.
Und 0-Bytes aus einem AnsiString rauszufiltern ist nie Sinn der Sache. |
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Ohhh oder viel besser Uhhhnicode ok, ich fange an zu verstehen und lerne daraus, Danke!
edit Ich habe mal eine mini-Kontrolle eingebaut um zu schauen ob was verloren geht, Memo1 scheint bei diesen Korea Zeichen mehr Chars zu verwenden als reinkommen oder ist das wegen CRLF?
Delphi-Quellcode:
i := Length(Memo1.Lines.Text) ;
Memo1.Lines.Add('HTTP HTML Source from: '+Temp1); Memo1.Lines.Add('Downloaded: '+IntToStr(Length(Temp2)) +' bytes, displaying: ' +IntToStr(i)+ ' chars. ' +IntToStr(Length(Temp2)-i)+ ' bytes are lost!'); Zitat:
|
AW: Mit IdHTTP Seite aufrufen und an MemoryStream übergeben = Zeichen fehlerhaft
Hallo nochmal,
hier zwei neue Samples die auch HTTPS Unterstützen, diesmal sollte nichts schiefgehen, aber mal abwarten was so kommt :lol:
Delphi-Quellcode:
Und hier die WinApi Variante, sollte auch HTTPS tauglich sein.
Uses WinInet;
function GetUrlContent(const Url: string): UTF8String; var NetHandle: HINTERNET; UrlHandle: HINTERNET; Buffer: array[0..1023] of byte; BytesRead: dWord; StrBuffer: UTF8String; begin Result := ''; NetHandle := InternetOpen('Delphi-PRAXiS RockZ', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); if Assigned(NetHandle) then try UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0); if Assigned(UrlHandle) then try repeat InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead); SetString(StrBuffer, PAnsiChar(@Buffer[0]), BytesRead); Result := Result + StrBuffer; until BytesRead = 0; finally InternetCloseHandle(UrlHandle); end else raise Exception.CreateFmt('Cannot open URL %s', [Url]); finally InternetCloseHandle(NetHandle); end else raise Exception.Create('Unable to initialize Wininet'); end; procedure TForm1.Button1Click(Sender: TObject); var temp1, temp2: String; i : Integer; begin Memo1.Clear; Temp1 := ''; Temp2 := ''; Memo1.Lines.Add('Downloading Data from ' +Edit1.Text); Memo1.Lines.Add('Please Wait...'); Temp1 := Edit1.Text; if Length(Temp1) > 0 then Temp2 := GetUrlContent(Temp1); Memo1.Lines.Text := Temp2; i := Length(Memo1.Lines.Text) ; Memo1.Lines.Add('HTTP/S HTML Source from: '+Temp1); Memo1.Lines.Add('Downloaded: '+IntToStr(Length(Temp2)) +' bytes, displaying: ' +IntToStr(i)+ ' chars. ' +IntToStr(Length(Temp2)-i)+ ' bytes are different!'); end;
Delphi-Quellcode:
Total Oldschool way, ich hoffe es gefällt Dir und löst Dein Problem!
procedure TForm1.Button1Click(Sender: TObject);
var http: variant; temp1, temp2: String; i : Integer; begin Memo1.Clear; Temp1 := ''; Temp2 := ''; Memo1.Lines.Add('Downloading Data from ' +Edit1.Text); Memo1.Lines.Add('Please Wait...'); Temp1 := Edit1.Text; http:=createoleobject('WinHttp.WinHttpRequest.5.1'); http.open('GET', Temp1, false); http.send; Temp2 := http.responsetext; Memo1.Lines.Text := Temp2; i := Length(Memo1.Lines.Text) ; Memo1.Lines.Add('HTTP/S HTML Source from: '+Temp1); Memo1.Lines.Add('Downloaded: '+IntToStr(Length(Temp2)) +' bytes, displaying: ' +IntToStr(i)+ ' chars. ' +IntToStr(Length(Temp2)-i)+ ' bytes are different!'); end; Hier der ![]() Falls "Nullen" zum Problem werden, schau in den anderen Code und passe das so an. edit PS: Und es tut mir leid das ich am Titel-Thema mehr als vorbeigerauscht sein sollte (beide Samples benötigen kein Indy und beide Samples enthalten keinen MemoryStream) PPS: Hier ein HTTPS Ergebnis :P Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:35 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