如何在TImage上显示Div背景图像

时间:2016-05-30 15:40:31

标签: html delphi background-image captcha

我有一个应用程序,它从各个站点收集信息以填充我的数据库。我被困在具有验证码的site上。我需要为我的用户显示验证码。问题是图片位于background-image中的DIV

DIV idcaptchaCodigo

我知道如何通过id和名称获取元素,使用值等等。但我不知道如何获取此图片或网址。

提前致谢

3 个答案:

答案 0 :(得分:1)

验证码非常具体,如果您使用他的网络链接,它将更改其文本。

我几天前解开了这个谜团,唯一的办法就是截取这个......

这里是我的代码的一些部分(它不漂亮,我仍然在做微调,但工作得很好):

主要程序,将位图保存到TImage:

 procedure TForm1.elscreenshot(var elid:string;imid:integer);  //elementID  and ImageID
    var
      doc : IHTMLDocument2;
      imgRange : IHTMLControlRange;
      img : IHTMLImgElement;
      render : IHTMLElementRender;

      bmp : TBitmap;
      _hdc : HDC;

      img_NameProp : string;
      img_idx,ii : Integer;
    begin
      doc := embeddedwb1.Document as IHTMLDocument2;
      imgRange := ( doc.body as HTMLBody ).createControlRange as IHTMLControlRange;

      for ii := imid to imid do
        begin
        img_idx:=ii;
    repeat
          img := doc.images.item( img_idx, EmptyParam ) as IHTMLImgElement;
          application.ProcessMessages;
          inc(img_idx);
    until pos('andom',img.href)>0;   // USUALLY CAPTCHA HAS "RANDOM" WORD IN ITS HREF   - IN YOUR CASE IT's name is uuidCaptcha 




   img_NameProp := Utf8ToAnsi( UTF8Encode( img.nameProp ) );


        begin
          render := ( img as IHTMLElementRender );

          bmp := TBitmap.Create;
          try
            bmp.Width := img.Width;
            bmp.Height := img.Height;

            _hdc := bmp.Canvas.Handle;

            render.DrawToDC( _hdc );

            Image1.Picture.Assign( bmp );   // <- HERE is happening the screenshot
             cxtextedit1.setfocus;  //focusing my edit box for user interaction
          finally
            bmp.Free;
          end;
          break;
        end;
    end;
end;

我需要的另一个代码(获取元素ID和图像ID:

procedure TForm1.getcaptcha(var i:integer);

//程序体中的函数:

function GetElementsByClassName(ADoc: IDispatch; const strClassName: string): IHTMLElement;
var
  vDocument: IHTMLDocument2;
  vElementsAll: IHTMLElementCollection;
  vElement: IHTMLElement;
  I, ElementCount: Integer;
begin
  Result := nil;
  ElementCount := 0;
  if not Supports(ADoc, IHTMLDocument2, vDocument) then
    raise Exception.Create('Invalid HTML document');
  vElementsAll := vDocument.all;
  for I := 0 to vElementsAll.length - 1 do
    if Supports(vElementsAll.item(I, EmptyParam), IHTMLElement, vElement) then
      if SameText(vElement.className, strClassName) then
      begin
        Result := vElement;
      end;
end;

程序

  var
        x:integer;
           Doc3 :  IHTMLDocument3;
          cpt : ihtmlelement;
          el:string;
        begin

             Doc3 := EmbeddedWB1.Document as IHTMLDocument3;
        cpt:=nil;
        repeat application.processmessages;until embeddedwb1.ReadyState>2;
        repeat
        application.ProcessMessages;
          cpt:=getelementsbyclassname(doc3,'input-captcha input-text');  //here You must fint how its Your element named  (use getinnertext and parse, or something similar
        until cpt<>nil;  //this repeat..until waits for captcha image to be loaded, usually it takes longer than the rest of webpage code (on slower connections)
          if assigned(cpt) then begin
          el:=cpt.id;
        elscreenshot(el,x);
        end;

        end;

希望它有所帮助:)

答案 1 :(得分:1)

您无法获取此图片的网址,因为它未通过标准HTML协议传输。

此类场景中的图片通常作为数据流传输,然后在客户端正确显示。

在您的情况下,图像实际上是以base64字符串从服务器传输到您的计算机,然后在您的计算机上解码为实际图像。

您可以通过巧妙地使用可以使用F12键激活的Google Chrome developer tools来获取此信息。

以这种方式实施此操作的主要原因是为了防止网络机器人克服captcha安全性。

事实上,大多数使用captcha保护系统的网站都会出于某种原因使用它。

最常见的原因是通过在网站上发布各种垃圾邮件内容来防止网络服务器对服务器造成严重破坏。

另一个原因是通过下载所有网站内容来防止它们超载服务器。

实际上,您尝试从该站点收集信息并将其存储在您自己的数据库中可能会直接违反站点使用协议。

基于所提到的网站与管辖权制度相关,我愿意打赌,不得以任何方式复制或重新分发网站上发布的任何信息。

答案 2 :(得分:1)

图片为base64 encoding,您需要将其转换为html代码并将其转换为位图请勿忘记将uuidCaptcha发送给您的帖子请求,该请求是识别验证码的ID输入你的程序。

uses Soap.EncdDecd, IdHTTP, System.StrUtils, pngimage;

Function _ExtractBetweenTags(Const s, LastTag, FirstTag: string; TrimTags: Boolean = True): string;
var
  pLast,pFirst,pNextFirst : Integer;
begin
  pFirst := Pos(FirstTag,s);
  pLast := Pos(LastTag,s);
  while (pLast > 0) and (pFirst > 0) do begin
    if (pFirst > pLast) then // Find next LastTag
      pLast := PosEx(LastTag,s,pLast+Length(LastTag))
    else
    begin
      pNextFirst := PosEx(FirstTag,s,pFirst+Length(FirstTag));
      if (pNextFirst = 0) or (pNextFirst > pLast) then begin
        if TrimTags then begin
          Result := Trim(StringReplace(Trim(Copy(s,pFirst,pLast-pFirst+Length(LastTag))), LastTag, '', [rfReplaceAll, rfIgnoreCase]));
          Result := Trim(StringReplace(Result, FirstTag, '', [rfReplaceAll, rfIgnoreCase]));
        end
        else
        Result := Trim(Copy(s,pFirst,pLast-pFirst+Length(LastTag)));
        Exit;
      end
      else
        pFirst := pNextFirst;
    end;
  end;
  Result := '';
end;

procedure TForm4.btn1Click(Sender: TObject);
var
  Input: TStringStream;
  Output: TBytesStream;
  sTmp, uuidCaptcha, captchaCodigo: string;
  IdHTTP: TIdHTTP;
  Graphic: TGraphic;
begin
  IdHTTP := TIdHTTP.Create(nil);
  try
    IdHTTP.AllowCookies := True;
    IdHTTP.HandleRedirects := True;
    IdHTTP.Request.Connection := 'keep-alive';
    IdHTTP.Request.UserAgent := 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36';
    sTmp := IdHTTP.Get('http://www.tjms.jus.br/cpopg5/imagemCaptcha.do');
    uuidCaptcha := _ExtractBetweenTags(sTmp, '"}', '"uuidCaptcha": "'); // You need this when you send the post request
    captchaCodigo := _ExtractBetweenTags(sTmp, '", "labelValorCaptcha":', 'base64,');
    mmo1.Lines.Add(captchaCodigo);
    Input := TStringStream.Create(captchaCodigo, TEncoding.ASCII);
    try
      Output := TBytesStream.Create;
      try
        Soap.EncdDecd.DecodeStream(Input, Output);
        Output.Position := 0;
        Graphic := TPngImage.Create;
        try
          Graphic.LoadFromStream(Output);
          img1.Picture.Bitmap.Assign(Graphic);  // Your Image loads here
        finally
          Graphic.Free;
        end;
      finally
        Output.Free;
      end;
    finally
      Input.Free;
    end;
  finally
    IdHTTP.Free;
  end;
end;