How to download a web page into a variable?
Using Indy:
uses IdHTTP;
const
HTTP_RESPONSE_OK = 200;
function GetPage(aURL: string): string;
var
Response: TStringStream;
HTTP: TIdHTTP;
begin
Result := '';
Response := TStringStream.Create('');
try
HTTP := TIdHTTP.Create(nil);
try
HTTP.Get(aURL, Response);
if HTTP.ResponseCode = HTTP_RESPONSE_OK then begin
Result := Response.DataString;
end else begin
// TODO -cLogging: add some logging
end;
finally
HTTP.Free;
end;
finally
Response.Free;
end;
end;
Using the native Microsoft Windows WinInet API:
function WebGetData(const UserAgent: string; const URL: string): string;
var
hInet: HINTERNET;
hURL: HINTERNET;
Buffer: array[0..1023] of AnsiChar;
BufferLen: cardinal;
begin
result := '';
hInet := InternetOpen(PChar(UserAgent), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if hInet = nil then RaiseLastOSError;
try
hURL := InternetOpenUrl(hInet, PChar(URL), nil, 0, 0, 0);
if hURL = nil then RaiseLastOSError;
try
repeat
if not InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen) then
RaiseLastOSError;
result := result + UTF8Decode(Copy(Buffer, 1, BufferLen))
until BufferLen = 0;
finally
InternetCloseHandle(hURL);
end;
finally
InternetCloseHandle(hInet);
end;
end;
Try it:
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Text := WebGetData('My Own Client', 'http://www.bbc.co.uk')
end;
But this only works if the encoding is UTF-8. So, to make it work in other cases, you either have to handle these separately, or you can use the Indy high-level wrappers, as suggested by Marjan. I admit they are superior in this case, but I still want to promote the underlying API, if for no other reason than educational...