我有一个应用程序,它从各个站点收集信息以填充我的数据库。我被困在具有验证码的site上。我需要为我的用户显示验证码。问题是图片位于background-image
中的DIV
。
DIV id
为captchaCodigo
。
我知道如何通过id和名称获取元素,使用值等等。但我不知道如何获取此图片或网址。
提前致谢
答案 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;