Por qué no puedo ir a buscar una imagen Captcha AOL en mi programa de Delphi?
Pregunta
Nuevo código de demostración:
Estoy tratando de obtener la imagen de un código de imagen AOL y sigo recibiendo un error 418.
unit imageunit;
///
/// https://new.aol.com/productsweb/
///
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL,
IdSSLOpenSSL, IdIntercept, IdZLibCompressorBase, IdCompressorZLib,
IdCookieManager, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
IdHTTP,jpeg,GIFImg, ExtCtrls, PerlRegEx;
type
TForm2 = class(TForm)
IdHTTP1: TIdHTTP;
IdCookieManager1: TIdCookieManager;
IdCompressorZLib1: TIdCompressorZLib;
IdConnectionIntercept1: TIdConnectionIntercept;
IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
Panel1: TPanel;
Image1: TImage;
Panel2: TPanel;
Button1: TButton;
PerlRegEx1: TPerlRegEx;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
function getaimcaptchaimage(data:string):string;
var
Regex: TPerlRegEx;
ResultString: string;
begin
Regex := TPerlRegEx.Create(nil);
Regex.RegEx := '<img src="/productsweb/WordVerImage?(.*?)"';
Regex.Options := [preCaseless];
Regex.Subject := data;
if Regex.Match then begin
if Regex.SubExpressionCount >= 1 then begin
ResultString := Regex.SubExpressions[1];
end;
result:=Resultstring;
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
JPI : TJPEGImage;
streamdata:TMemoryStream;
SStream: Tstringstream;
website:string;
begin
streamdata := TMemoryStream.Create;
SStream := tstringstream.Create ( '' );
try
idhttp1.Get('https://new.aol.com/productsweb/',SStream);
memo1.Text:=UTF8ToWideString ( SStream.DataString );
website:='https://new.aol.com/productsweb/WordVerImage'+getaimcaptchaimage( UTF8ToWideString ( SStream.DataString ));
form2.Caption:=website;
idhttp1.Get(website, Streamdata);
Except
{ Handle exceptions }
On E : Exception Do
Begin
MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0);
End;
End;
//https://new.aol.com/productsweb/WordVerImage?20890843
//https://new.aol.com/productsweb/WordVerImage?91868359
///
/// gives error 418 unused
///
streamdata.Position := 0;
JPI := TJPEGImage.Create;
Try
JPI.LoadFromStream ( streamdata );
Finally
Image1.Picture.Assign ( JPI );
JPI.Free;
streamdata.Free;
End;
end;
end.
Forma:
object Form2: TForm2
Left = 0
Top = 0
Caption = 'Form2'
ClientHeight = 247
ClientWidth = 480
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 0
Top = 41
Width = 480
Height = 206
Align = alClient
TabOrder = 0
object Image1: TImage
Left = 1
Top = 1
Width = 478
Height = 115
Align = alClient
ExplicitLeft = 5
ExplicitTop = 17
ExplicitWidth = 200
ExplicitHeight = 70
end
object Memo1: TMemo
Left = 1
Top = 116
Width = 478
Height = 89
Align = alBottom
TabOrder = 0
ExplicitLeft = 80
ExplicitTop = 152
ExplicitWidth = 185
end
end
object Panel2: TPanel
Left = 0
Top = 0
Width = 480
Height = 41
Align = alTop
TabOrder = 1
object Button1: TButton
Left = 239
Top = 6
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
end
object IdHTTP1: TIdHTTP
Intercept = IdConnectionIntercept1
IOHandler = IdSSLIOHandlerSocketOpenSSL1
MaxAuthRetries = 100
AllowCookies = True
HandleRedirects = True
RedirectMaximum = 100
ProxyParams.BasicAuthentication = False
ProxyParams.ProxyPort = 0
Request.ContentLength = -1
Request.Accept =
'image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-s' +
'hockwave-flash, application/cade, application/xaml+xml, applicat' +
'ion/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-' +
'application, */*'
Request.BasicAuthentication = False
Request.Referer = 'http://www.yahoo.com'
Request.UserAgent =
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.1) Gecko/201001' +
'22 firefox/3.6.1'
HTTPOptions = [hoForceEncodeParams]
CookieManager = IdCookieManager1
Compressor = IdCompressorZLib1
Left = 40
Top = 160
end
object IdCookieManager1: TIdCookieManager
Left = 360
Top = 136
end
object IdCompressorZLib1: TIdCompressorZLib
Left = 408
Top = 56
end
object IdConnectionIntercept1: TIdConnectionIntercept
Left = 304
Top = 72
end
object IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL
Intercept = IdConnectionIntercept1
MaxLineAction = maException
Port = 0
DefaultPort = 0
SSLOptions.Mode = sslmUnassigned
SSLOptions.VerifyMode = []
SSLOptions.VerifyDepth = 0
Left = 192
Top = 136
end
object PerlRegEx1: TPerlRegEx
Options = []
Left = 120
Top = 56
end
end
Si usted va a https://new.aol.com/productsweb/ se dará cuenta de la imagen CAPTCHA tiene una URL como https://new.aol.com/productsweb/ WordVerImage? 91868359
Me puso esa URL en el cuadro de edición y obtener un error.
Lo que está mal con este código?
Solución
a mis viejos proyectos que estaba código de imagen readed desde web. he hecho esto con los procedimientos de caché componente navegador web integrado. así que si usted puede leer los archivos temporales de Internet de su código se puede leer los datos de imagen de la memoria caché. i añadido un código simple a continuación,
las funciones ClearAllEntries GetCachedFileFromURL y se declarated en la unidad TEmbeddedWebBrowser. i sólo se utilizó el código copiado en mi solución para el tamaño exe inferior. pero se puede utilizar una fuente actualizada de los componentes. el componente es de código abierto.
uses
WinInet;
function GetCachedFileFromURL(strUL: string; var strLocalFile: string): Boolean;
var
lpEntryInfo: PInternetCacheEntryInfo;
hCacheDir: LongWord;
dwEntrySize: LongWord;
dwLastError: LongWord;
begin
Result := False;
dwEntrySize := 0;
// Begin the enumeration of the Internet cache.
FindFirstUrlCacheEntry(nil, TInternetCacheEntryInfo(nil^), dwEntrySize);
GetMem(lpEntryInfo, dwEntrySize);
hCacheDir := FindFirstUrlCacheEntry(nil, lpEntryInfo^, dwEntrySize);
if (hCacheDir <> 0) and (strUL = lpEntryInfo^.lpszSourceUrlName) then
begin
strLocalFile := lpEntryInfo^.lpszLocalFileName;
Result := True;
end;
FreeMem(lpEntryInfo);
if Result = False then
repeat
dwEntrySize := 0;
// Retrieves the next cache group in a cache group enumeration
FindNextUrlCacheEntry(hCacheDir, TInternetCacheEntryInfo(nil^), dwEntrySize);
dwLastError := GetLastError();
if (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
begin
GetMem(lpEntryInfo, dwEntrySize);
if (FindNextUrlCacheEntry(hCacheDir, lpEntryInfo^, dwEntrySize)) then
begin
if strUL = lpEntryInfo^.lpszSourceUrlName then
begin
strLocalFile := lpEntryInfo^.lpszLocalFileName;
Result := True;
Break;
end;
end;
FreeMem(lpEntryInfo);
end;
until (dwLastError = ERROR_NO_MORE_ITEMS);
end;
procedure TForm1.ClearCache();
begin
SearchPattern := spAll;
ClearAllEntries;
end;
uso
procedure TForm1.Button1Click(Sender: TObject);
var
fname:string;
jpImg:TJPEGImage;
begin
ClearCache;
try
jpImg:=TJPEGImage.Create;
GetCachedFileFromURL('https://ebildirge.ssk.gov.tr/WPEB/PG',fname);
jpImg.LoadFromFile(fname);
finally
FreeAndNil(jpgImg);
end;
end;
Otros consejos
Hay una cookie en cuestión. Si vas directamente a la URL del código de imagen https://new.aol.com/productsweb/WordVerImage?91868359 en un navegador que no ha visitado https://new.aol.com/productsweb/ a continuación, se obtiene (después de una actualización):
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>418 unused</title>
</head><body>
<h1>unused</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator,
null and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>
Sin embargo, si usted visita https://new.aol.com/productsweb/ en primer lugar, a continuación, obtendrá una imagen. Borrar la cookie y se obtiene el error de nuevo (aunque, como se señaló Francois, no obtiene respuesta en primer lugar, y después de actualizar a obtener la imagen.)
soportes Indy cookies, por lo que tendrá que añadir soporte para cookies, y luego o bien obtener la cookie visitando el productsweb primero, o simularlo de un valor conocido.
Se dará cuenta de que la imagen generada no se basa en el número pasa como un parámetro solamente, sino también la cookie. Tener dos navegadores diferentes (Chrome y Firefox) que tienen cada uno una cookie distinta, y luego visitar la misma URL código de imagen y obtendrá dos imágenes diferentes.
curioso lo que está tratando de lograr con esto.
Creo que significa "desaparece". De alguna manera, a través de los encabezados o algo en su solicitud, es determinar que hueles como un robot. Tal vez porque usted está pidiendo una imagen que se sabe que no sólo hizo para usted. Sí, eso es probablemente él. Si voy a la URL en el navegador, consigo un 418 también.
No es su código. tratar en un navegador ....
(Obviamente, se necesita para eliminar los espacios en blanco de la 'h t t p s' ...)
Esta https://new.aol.com/productsweb/
URL aparentemente necesita ser llamado antes de poder obtener una imagen de código de imagen. De lo contrario se obtiene una (inadecuada) 418 Unused
error.
A veces tenía que tratar dos veces con la imagen # como llegué por primera vez un error de 420 Unused
...
Es mejor que pedirles, como su API en realidad no parece estable ...
RE: http 418 broma. Si quieres un poco de diversión con el http códigos de error de lectura en Un desarrollador web y su novia (s)