使用NetHTTPClient

时间:2018-09-26 11:49:51

标签: delphi download

我正在使用Delphi 10.2.3。

我想从http://www.boi.org.il/currency.xml下载每日汇率

我的设计时组件设置:

NetHTTPClient1.AllowCookies := True;
NetHTTPClient1.HandleRedirects := True;
NetHTTPClient1.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.108 Safari/537.36';

NetHTTPRequest1.MethodString := 'GET';
NetHTTPRequest1.URL := 'http://www.boi.org.il/currency.xml';

我的代码很简单:

XML := NetHTTPRequest1.Execute().ContentAsString();

我在XML变量中得到的是:

<html><body><script>document.cookie='sssssss=6ed9ca3asssssss_6ed9ca3a; path=/';window.location.href=window.location.href;</script></body></html>

当我尝试使用网络浏览器(在我的情况下为Opera)时,可以使用与上述相同的URL看到正确的XML。我看不出是什么问题。

感谢您的帮助。

修改: 阅读@NineBerry的评论后,我使用Fiddler来监视到站点的每个数据包。那表明我浏览器在实际可以下载XML之前进行了三次请求。第二个请求,浏览器在对第一个请求的响应中添加cookie引用。第三个请求与2ns请求相同。

经过下面的调查,这是我的有效代码,我没有更改任何TNetHTTPClient.UserAgent参数:

function DownloadExchangeRates(const URL: string; out XML: string): Boolean;
var
  Cookie: string;
  Path: string;
  AURI: TURI;
  AClient: TNetHTTPClient;
  ARequest: TNetHTTPRequest;
begin
  AClient := nil;
  ARequest := nil;
  try
    AClient := TNetHTTPClient.Create(nil);
    AClient.AllowCookies := True;
    AClient.HandleRedirects := True;

    ARequest := TNetHTTPRequest.Create(nil);
    ARequest.Client := AClient;
    ARequest.Asynchronous := False;
    ARequest.MethodString := 'GET';
    ARequest.URL := URL;
    ARequest.CustomHeaders['Pragma'] := 'no-cache';

    try
      XML := ARequest.Execute().ContentAsString();
      if XML.Length > 5 then
      begin
        if UpperCase(XML.Substring(0, 6)) = '<HTML>' then
        begin
          Cookie := GetCookie(XML);
          AURI := TURI.Create(URL);
          Path := AURI.SCHEME_HTTP + '://' + AURI.Host + '/';
          AClient.CookieManager.AddServerCookie(Cookie, Path);
          AClient.CookieManager.AddServerCookie(Cookie, URL);
          ARequest.CustomHeaders['Referer'] := URL;
          XML := ARequest.Execute().ContentAsString();
          if XML.Length > 5 then
          begin
            if UpperCase(XML.Substring(0, 6)) = '<HTML>' then
            begin
              XML := ARequest.Execute().ContentAsString();
            end;
          end;
        end;
      end;
    except
      on E: Exception do
      begin
        Exit(False);
      end;
    end;
  finally
    ARequest.Free();
    AClient.Free();
  end;

  Result := (XML.Length > 2) and (XML[2] = '?');
end;

1 个答案:

答案 0 :(得分:0)

uses 
  System.Net.HttpClient;

function TUpdater.DownloadFile(const aURL: string; aStream: TStream): boolean;
var
  vHTTP: THTTPClient;
begin
  Assert(aStream <> nil);
  vHTTP := THTTPClient.Create;
  try
     Result := vHTTP.Get(aURL, aStream).StatusCode = 200;
  finally
    vHTTP.Free;
  end;
end;