Delphi 如何处理Clouflare,在执行Idhttp.get时,我使用Cloudflare而不是实际的站点源代码

Delphi 如何处理Clouflare,在执行Idhttp.get时,我使用Cloudflare而不是实际的站点源代码,delphi,indy,cloudflare,idhttp,Delphi,Indy,Cloudflare,Idhttp,我正在尝试执行一个简单的IdHttp.get,但是我得到的响应给了我一个CloudFlare页面,上面写着在访问之前检查浏览器… 我该如何处理这个问题呢?我尝试了我能想到的任何选项,我甚至尝试了Sleep(6000)并重复IdHttp.get,因为CloudFlare消息说等待5秒钟 这是我的代码: var mIdHttp: TIdHttp; URL: String; memoryStream: TMemoryStream; Begin mIdHttp := TId

我正在尝试执行一个简单的
IdHttp.get
,但是我得到的响应给了我一个
CloudFlare
页面,上面写着
在访问之前检查浏览器…

我该如何处理这个问题呢?我尝试了我能想到的任何选项,我甚至尝试了
Sleep(6000)
并重复
IdHttp.get
,因为
CloudFlare
消息说
等待5秒钟

这是我的代码:

var 
  mIdHttp: TIdHttp;  
  URL: String;  
  memoryStream: TMemoryStream;
Begin  
  mIdHttp := TIdHttp.create(nil);
  mIdHttp.AllowCookies := true;
  mIdHttp.HandleRedirects := true;
  mIdHttp.Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36 OPR/44.0.2510.1457';
  mIdHttp.Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8';
  mIdHttp.Request.AcceptEncoding := 'gzip, deflate';
  mIdHttp.Request.AcceptLanguage := 'en-US,en;q=0.9';
  mIdHttp.Request.Host := 'somesite.com/'';  
  URL := 'https://somesite.com'';  
  //Both ssleay32.dll and libeay32.dll are beside the application.
  mIdHttp.get(URL, memoryStream);  
  memoryStream.saveToFile('response.txt');  
End;

Cloudflare实现了对机器人(DDoS攻击等)的保护,这就是5秒等待的意义

您的应用程序不是执行Javascript的web浏览器,因此它被视为一个机器人

Cloudflare以Javascript发送一个质询,必须计算该质询并将其发送回Cloudflare,以便获得一个cookie,然后该cookie可用于绕过后续请求的保护


以上链接适用于C#。您必须使用Indy和您想要的任何Javascript/Regex库在Delphi中复制类似的解决方案

Cloudflare实施防僵尸程序(DDoS攻击等)的保护,这就是5秒等待的意义所在

您的应用程序不是执行Javascript的web浏览器,因此它被视为一个机器人

Cloudflare以Javascript发送一个质询,必须计算该质询并将其发送回Cloudflare,以便获得一个cookie,然后该cookie可用于绕过后续请求的保护


以上链接适用于C#。您必须使用Indy和您想要的任何Javascript/Regex库在Delphi中复制类似的解决方案

我解决了这个问题,首先将indy版本更新为10.6.2.0,然后按照下面的请求代码进行操作:

函数请求(方法,URL:String;RequestHeaders,SendString:String;tradtlog:tloger;ContentType:String='application/x-www-form-urlencoded'
;SSLVersion:tidslversion=sslv23;UserAgent:string='Mozilla/5.0(WindowsNT6.1;WOW64;rv:53.0)Gecko/20100101 Firefox/53.0'):string;
变量
SendStream、GetSStream:TStringStream;
IdHTTP:TIdHTTP;
列表:TStringList;
LHandler:TIdSSLIOHandlerSocketOpenSSL;
埃夫汉德勒:特文坦德勒;
IdConnectionIntercept:TIdConnectionIntercept;
i:整数;
RetStr,S,KEY,VALUE:string;
开始
结果:='';
如果URL='',则退出;
IdHTTP:=TIdHTTP.Create(nil);
列表:=TStringList.Create;
SendStream:=TStringStream.Create(“”);
GetSStream:=TStringStream.Create(“”);
尝试
提取字符串(['&'],[],pchar(RequestHeaders),List);
SendStream.WriteString(SendString);
尝试
IdConnectionIntercept:=TIdConnectionIntercept.Create(nil);
IdConnectionIntercept.OnReceive:=EvHandler.IdConnectionInterceptReceive;
IdConnectionIntercept.OnSend:=EvHandler.IdConnectionInterceptSend;
IDHTTP.Intercept:=IdConnectionIntercept;
如果(pos('HTTPS',大写(URL))>0),则
开始
LHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(IDHTTP);
IdHTTP.IOHandler:=LHandler;
LHandler.OnVerifyPeer:=EvHandler.lhandlervifypeer;
LHandler.SSLOptions.Method:=SSLVersion;
LHandler.SSLOptions.SSLVersions:=[SSLV23,SSLV2,sslvSSLv3,sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2];
LHandler.SSLOptions.Mode:=sslmUnassigned;
LHandler.SSLOptions.VerifyMode:=LHandler.SSLOptions.VerifyMode+[sslvrfPeer];;
LHandler.SSLOptions.VerifyDepth:=0;
结束
else IdHTTP.IOHandler:=nil;
对于i:=0到List.Count-1 do
开始
S:=修剪(列表字符串[i]);
如果是“”,那么
开始
键:=副本(S,1,位置('=',S)-1);
值:=副本,位置('=',S)+1,长度(S));
IdHTTP.Request.CustomHeaders.Add(键+':'+值);
结束;
结束;
IdHTTP.Request.ContentType:=ContentType;
IdHTTP.Request.UserAgent:=UserAgent;
IdHTTP.HandlerRedirects:=True;
IdHTTP.AllowCookies:=True;
IdHTTP.Request.Connection:='keep-alive';
IdHTTP.Request.BasicAuthentication:=False;
IdHTTP.Request.Accept:=“text/html,*/*”;
IdHTTP.Request.AcceptEncoding:='identity';
//IdHTTP.ReadTimeout:=MySysPM.PMA06;
//IdHTTP.ConnectTimeout:=MySysPM.PMA06;
IdHTTP.HTTPOptions:=IdHTTP.HTTPOptions+[hoKeepOrigProtocol];
IdHTTP.ProtocolVersion:=pv1_1;
IdHTTP.Request.Referer:='';
如果大写(Method)=“POST”,则
开始
Post(URL、SendStream、GetSStream);
RetStr:=Utf8ToAnsi(GetSStream.DataString);
结束
否则,如果大写(方法)=“GET”,则
开始
RetStr:=IdHTTP.Get(URL);
结束
否则开始
删除(URL);
结束;
IdHTTP.Disconnect;
结果:=RetStr
除了
关于E:exception-do
开始
WriteLog('Request:'+e.Message,1);
结束;
结束;
最后
尝试
如果已分配(IdConnectionIntercept),则为FreeAndNil(IdConnectionIntercept);
FreeAndNil(LHandler);
FreeAndNil(SendStream);
FreeAndNil(GetSStream);
FreeAndNil(列表);
FreeAndNil(IdHTTP);
除了
结束;
结束;
结束;

我解决了这个问题,首先将indy版本更新为10.6.2.0,然后按照下面的请求代码进行操作:

函数请求(方法,URL:String;RequestHeaders,SendString:String;tradtlog:tloger;ContentType:String='application/x-www-form-urlencoded'
;SSLVersion:tidslversion=sslv23;UserAgent:string='Mozilla/5.0(WindowsNT6.1;WOW64;rv:53.0)Gecko/20100101 Firefox/53.0'):string;
变量
SendStream、GetSStream:TStringStream;
IdHTTP:TIdHTTP;
列表:TStringList;
LHandler:TIdSSLIOHandlerSocketOpenSSL;
埃夫汉德勒:特文坦德勒;
IdConnectionIntercept:TIdConnectionIntercept;
i:整数;
RetStr,S,KEY,VALUE:string;
开始
结果:='';
如果URL='',则退出;
IdHTTP:=TIdHTTP.Create(nil);
列表:=TStringList.Create;
SendStream:=TStringStream.Create(“”);
GetSStream:=TStrin
function Request(Method,URL:String;RequestHeaders,SendString:String;TreadTLog:TLogger;ContentType:string='application/x-www-form-urlencoded'
  ;SSLVersion:TIdSSLVersion=sslvSSLv23;UserAgent:string='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0'):string;
var
  SendStream,GetSStream: TStringStream;
  IdHTTP:TIdHTTP;
  List:TStringList;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
  EvHandler:TEventHandlers;
  IdConnectionIntercept:TIdConnectionIntercept;
  i:Integer;
  RetStr,S,KEY,VALUE:string;  
begin
  Result:='';
  if URL='' then Exit;
  IdHTTP:=TIdHTTP.Create(nil);
  List := TStringList.Create;  
  SendStream:=TStringStream.Create('');
  GetSStream:=TStringStream.Create('');
  try

    ExtractStrings(['&'],[],pchar(RequestHeaders),List);
    SendStream.WriteString(SendString);
    try
      IdConnectionIntercept:= TIdConnectionIntercept.Create(nil);
      IdConnectionIntercept.OnReceive := EvHandler.IdConnectionInterceptReceive;
      IdConnectionIntercept.OnSend := EvHandler.IdConnectionInterceptSend;
      IDHTTP.Intercept := IdConnectionIntercept;   

      if (pos('HTTPS',UPPERCASE(URL))>0) then
      begin
        LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IDHTTP);
        IdHTTP.IOHandler:=LHandler;
        LHandler.OnVerifyPeer:=EvHandler.LHandlerVerifyPeer;
        LHandler.SSLOptions.Method := SSLVersion;
        LHandler.SSLOptions.SSLVersions:=[sslvSSLv23,sslvSSLv2, sslvSSLv3, sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2];
        LHandler.SSLOptions.Mode := sslmUnassigned;
        LHandler.SSLOptions.VerifyMode := LHandler.SSLOptions.VerifyMode + [sslvrfPeer];;
        LHandler.SSLOptions.VerifyDepth := 0;   
      end
      else IdHTTP.IOHandler:=nil;
      for i:=0 to List.Count-1 do
      begin
        S:=Trim(List.Strings[i]);
        if S<>'' then
        begin
          KEY:=Copy(S,1,Pos('=',S)-1);
          VALUE:=Copy(S,Pos('=',S)+1,Length(S));
          IdHTTP.Request.CustomHeaders.Add(KEY+':'+VALUE);
        end;
      end;
      IdHTTP.Request.ContentType :=ContentType;
      IdHTTP.Request.UserAgent:=UserAgent;

      IdHTTP.HandleRedirects := True;
      IdHTTP.AllowCookies := True;
      IdHTTP.Request.Connection:='keep-alive';
      IdHTTP.Request.BasicAuthentication := False;
      IdHTTP.Request.Accept:='text/html, */*';
      IdHTTP.Request.AcceptEncoding:='identity';
      //IdHTTP.ReadTimeout:=MySysPM.PMA06;
      //IdHTTP.ConnectTimeout:=MySysPM.PMA06;
      IdHTTP.HTTPOptions:=IdHTTP.HTTPOptions+[hoKeepOrigProtocol];
      IdHTTP.ProtocolVersion:=pv1_1;
      IdHTTP.Request.Referer:='';  

      IF UpperCase(Method)='POST' then
      BEGIN
        IdHTTP.Post(URL,SendStream,GetSStream);
        RetStr:=Utf8ToAnsi(GetSStream.DataString);
      end
      else if UpperCase(Method)='GET' then
      begin
        RetStr:=IdHTTP.Get(URL);
      end
      else begin
        IdHTTP.Delete(URL);
      end;
      IdHTTP.Disconnect;
      Result:=RetStr
    except
      on E:exception do
      begin
        TreadTLog.WriteLog('Request:'+e.Message,1);
      end;
    end;
  finally
    try
      if Assigned(IdConnectionIntercept) then FreeAndNil(IdConnectionIntercept);
      FreeAndNil(LHandler);
      FreeAndNil(SendStream);
      FreeAndNil(GetSStream);
      FreeAndNil(List);
      FreeAndNil(IdHTTP);
    except
    end;
  end;
end;