Delphi使用Indy、ICS组件读取网页
Delphi使用Indy、ICS组件读取网页
使用Indy 10中TIdHTTP的例子:
代码
uses
IdHttp;
.
.
.
function HttpGet(const Url: string; var Html: string): Boolean;
var
HttpClient: TIdHTTP;
begin
Result := False;
HttpClient := TIdHTTP.Create(nil);
try
Html := HttpClient.Get(Url);
Result := True;
except
on e: Exception do
begin
end;
end;
HttpClient.Free;
end;
IdHttp;
.
.
.
function HttpGet(const Url: string; var Html: string): Boolean;
var
HttpClient: TIdHTTP;
begin
Result := False;
HttpClient := TIdHTTP.Create(nil);
try
Html := HttpClient.Get(Url);
Result := True;
except
on e: Exception do
begin
end;
end;
HttpClient.Free;
end;
Indy采用的是同步I/O的方式,而且在连接超时控制方面存在bug,因此TIdHttp.Get()有时会发生陷入死锁无法返回的问题。
使用ICS中THttpCli的例子:
代码
uses
HttpProt;
.
.
.
function HttpGet(const Url: string; var Html: string): Boolean;
var
HttpClient: THttpCli;
DataLen: Int64;
FailMsg: string;
begin
Result := False;
HttpClient := THttpCli.Create(nil);
HttpClient.URL := Url;
HttpClient.NoCache := True;
HttpClient.RcvdStream := TMemoryStream.Create;
try
try
HttpClient.Get;
DataLen := HttpClient.RcvdStream.Size;
SetLength(Html, DataLen);
HttpClient.RcvdStream.Position := 0;
HttpClient.RcvdStream.Read(PChar(Html)^, DataLen);
Result := True;
except
on E: EHttpException do
begin
FailMsg := Format('Failed : %d %s',
[HttpClient.StatusCode, HttpClient.ReasonPhrase]);
end else
raise;
end;
finally
HttpClient.RcvdStream.Free;
HttpClient.RcvdStream := nil;
HttpClient.Free;
end;
end;
HttpProt;
.
.
.
function HttpGet(const Url: string; var Html: string): Boolean;
var
HttpClient: THttpCli;
DataLen: Int64;
FailMsg: string;
begin
Result := False;
HttpClient := THttpCli.Create(nil);
HttpClient.URL := Url;
HttpClient.NoCache := True;
HttpClient.RcvdStream := TMemoryStream.Create;
try
try
HttpClient.Get;
DataLen := HttpClient.RcvdStream.Size;
SetLength(Html, DataLen);
HttpClient.RcvdStream.Position := 0;
HttpClient.RcvdStream.Read(PChar(Html)^, DataLen);
Result := True;
except
on E: EHttpException do
begin
FailMsg := Format('Failed : %d %s',
[HttpClient.StatusCode, HttpClient.ReasonPhrase]);
end else
raise;
end;
finally
HttpClient.RcvdStream.Free;
HttpClient.RcvdStream := nil;
HttpClient.Free;
end;
end;
ICS使用的是异步I/O,其TFtpClient组件有Timout属性可以对连接超时进行控制,而THttpCli组件没有。但可以采用在定时器中调用THttpCli.Abort()取消连接的方式控制超时,也可以显式调用异步方法:
var
HttpClient: THttpCli;
DataLen:
Int64
;
FailMsg:
string
;
Tick:
Cardinal
;
begin
Result :=
False
;
HttpClient := THttpCli
.
Create(
nil
);
HttpClient
.
URL := Url;
HttpClient
.
NoCache :=
True
;
HttpClient
.
RcvdStream := TMemoryStream
.
Create;
Tick := GetTickCount;
try
try
HttpClient
.
GetASync;
while
HttpClient
.
State <> httpReady
do
//检测HTTP状态
begin
if
GetTickCount - Tick >
30
*
1000
then
//此处设置了30S超时,可根据需要修改此数值
begin
HttpClient
.
Abort;
Exit;
end
;
Application
.
ProcessMessages;
end
;
DataLen := HttpClient
.
RcvdStream
.
Size;
SetLength(Html, DataLen);
HttpClient
.
RcvdStream
.
Position :=
0
;
HttpClient
.
RcvdStream
.
Read(
PChar
(Html)^, DataLen);
Result :=
True
;
except
on
E: EHttpException
do
begin
FailMsg := Format(
'Failed : %d %s'
,
[HttpClient
.
StatusCode, HttpClient
.
ReasonPhrase]);
end
else
raise
;
end
;
finally
HttpClient
.
RcvdStream
.
Free;
HttpClient
.
RcvdStream :=
nil
;
HttpClient
.
Free;
end
;
end