Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Internet
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-03-2015
Jontart Jontart is offline
Miembro
 
Registrado: jun 2006
Posts: 13
Poder: 0
Jontart Va por buen camino
Problema con WebBrowser. Uno más.

Saludos cordiales,

hace bastante tiempo que no entro por aquí, y que no uso delphi, por lo que estoy bastante perdido.
Tengo un problema con un TWebBrowser, a la hora de mandar información a una página web por código.

Al pulsar un TButtom, meto la dirección de una página web, introduzco el usuario y el password que me piden y valido. Sin problemas.
Al pulsar un segundo TButtom, me dirigo a un link determinado de la página anterior. Sin problemas.
Al pulsar un tercer TButtom, edito un TEXAREA y hago un SUBMIT al servidor. También sin problemas.

El PROBLEMA está cuando intento hacerlo todo seguido, sin recurrir a los TButtom.

Código Delphi:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
Var
   ovElemento: OleVariant;
begin
// Cargo la página en cuestión
  WebBrowser1.Navigate('direccion pagina web');

// Espero a que esté totalmente cargada
   while webBrowser1.ReadyState < READYSTATE_INTERACTIVE do  Application.ProcessMessages;

// Doy valores a los elementos CONOCIDOS que me interesan
   ovElemento := WebBrowser1.OleObject.Document.forms.item(0).elements;

   ovElemento.item(1).value:='usuario';        // Escribe en la página el usuario
   ovElemento.item(2).value:='contraseña';  // Escribe en la página la password
   ovElemento.item(3).click;                      // Mandamos al servidor la información

end;

procedure TForm1.Button2Click(Sender: TObject);
Var
   ovElemento: OleVariant;
begin
   ovElemento:= WebBrowser1.OleObject.Document.links;
   ovElemento.item(38).click;  // Conozco el item que me interesa. No necesito buscarlo.
end;

procedure TForm1.Button3Click(Sender: TObject);
Var
   ovElemento: OleVariant;
begin
    ovElemento := WebBrowser1.OleObject.Document.forms.item(1).elements;

   ovElemento.item(2).value := 'Texto a enviar';  // Pongo el texto que necesito en un TextArea
   ovElemento.item(5).click;                             // Hago el Submit

end;

Hasta aquí funciona correctamente. Pero cuando quiero hacerlo todo seguido, por ejemplo al pulsar también un TButtom, no me sale.
Código Delphi [-]
procedure TForm1.Button4Click(Sender: TObject);
Var
   ovElemento: OleVariant;
begin
// Cargo la página en cuestión
   WebBrowser1.Navigate(''direccion pagina web'');

// Espero a que esté totalmente cargada
   while webBrowser1.ReadyState < READYSTATE_INTERACTIVE do  Application.ProcessMessages;

// Doy valores a los elementos CONOCIDOS que me interesan
   ovElemento := WebBrowser1.OleObject.Document.forms.item(0).elements;

   ovElemento.item(1).value:='usuario';        // Escribe en la página el usuario
   ovElemento.item(2).value:='contraseña';  // Escribe en la página la password
   ovElemento.item(3).click;                      // Mandamos al servidor la información

   ovElemento:= WebBrowser1.OleObject.Document.links;
   ovElemento.item(38).click;  // ********** AQUI FALLA ***************

   ovElemento := WebBrowser1.OleObject.Document.forms.item(1).elements;

   ovElemento.item(2).value := 'Texto a enviar'';  // Pongo el texto que necesito en un TextArea
   ovElemento.item(5).click;                             // Hago el Submit

end;
Seguramente será una tontería, o incluso de la página en cuestión, pero llevo dándole vueltas varios días y no consigo dar con la solución.

He comprobado que si antes del fallo interrumpo el programa, por ejemplo con un showmessage() , si me funciona. ¿¿??, pero con un sleep() no.

Gracias anticipadas.

Última edición por nlsgarcia fecha: 11-03-2015 a las 23:49:12. Razón: Sintaxis Delphi
Responder Con Cita
  #2  
Antiguo 12-03-2015
Jovalca Jovalca is offline
Miembro
NULL
 
Registrado: sep 2013
Ubicación: Madrid - España
Posts: 30
Poder: 0
Jovalca Va por buen camino
Hola Jontart.

Cuando haces esto, el webbrowser dirige a otra página?

Cita:
Empezado por Jontart Ver Mensaje
Código Delphi [-]
   
   ovElemento.item(1).value:='usuario';        // Escribe en la página el usuario
   ovElemento.item(2).value:='contraseña';  // Escribe en la página la password
   ovElemento.item(3).click;                      // Mandamos al servidor la información
Saludos.
Responder Con Cita
  #3  
Antiguo 12-03-2015
Jontart Jontart is offline
Miembro
 
Registrado: jun 2006
Posts: 13
Poder: 0
Jontart Va por buen camino
Si.
Es la típica entrada de usuario. Realmente, una vez pasada entra en la aplicación, aunque con la misma raiz.
Responder Con Cita
  #4  
Antiguo 12-03-2015
Jontart Jontart is offline
Miembro
 
Registrado: jun 2006
Posts: 13
Poder: 0
Jontart Va por buen camino
Para solventar el problema, y no entiendo bien porqué, lo que he hecho ha sido, puesto que observé que al hacer un showmessage() no se producía el error, crear un nuevo form "temporal", en el punto dónde dejaba de correr el programa; este nuevo form, abierto como showModal, se cierra el solito una vez pasados 3 segundos y la aplicación contínua tan ricamente.

NO sé porqué, pero me está funcionado. Me gustaría encontrar la forma elegante de hacerlo y el motivo por el que no funciona.

Saludos.
Responder Con Cita
  #5  
Antiguo 12-03-2015
Jovalca Jovalca is offline
Miembro
NULL
 
Registrado: sep 2013
Ubicación: Madrid - España
Posts: 30
Poder: 0
Jovalca Va por buen camino
Ok, se me ocurre así de pronto que quizá cuando lo haces con los botones, el tiempo que transcurre desde que hace login hasta que pulsas el siguiente botón, es suficiente para que la página donde se encuentra el link cargue completamente.

Pero cuando lo haces todo seguido no le das tiempo suficiente para que cargue con lo que creo le es imposible encontrar el item(38).

Has probado a esperar a que la página cargue después del login?

No lo he probado... Pero intenta poner la linea de espera también aqui o retrasar la segunda accion.

Código Delphi [-]
procedure TForm1.Button4Click(Sender: TObject);
Var
   ovElemento: OleVariant;
begin
// Cargo la página en cuestión
   WebBrowser1.Navigate(''direccion pagina web'');

// Espero a que esté totalmente cargada
   while webBrowser1.ReadyState < READYSTATE_INTERACTIVE do  Application.ProcessMessages;

// Doy valores a los elementos CONOCIDOS que me interesan
   ovElemento := WebBrowser1.OleObject.Document.forms.item(0).elements;

   ovElemento.item(1).value:='usuario';        // Escribe en la página el usuario
   ovElemento.item(2).value:='contraseña';  // Escribe en la página la password
   ovElemento.item(3).click;                      // Mandamos al servidor la información

   while webBrowser1.ReadyState < READYSTATE_INTERACTIVE do  Application.ProcessMessages;

   ovElemento:= WebBrowser1.OleObject.Document.links;
   ovElemento.item(38).click;  // ********** AQUI FALLA ***************

   ovElemento := WebBrowser1.OleObject.Document.forms.item(1).elements;

   ovElemento.item(2).value := 'Texto a enviar'';  // Pongo el texto que necesito en un TextArea
   ovElemento.item(5).click;                             // Hago el Submit

end;

Ya me diras si era eso.
Saludos.
Responder Con Cita
  #6  
Antiguo 12-03-2015
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.410
Poder: 22
fjcg02 Va camino a la fama
Como dice Jovalca, cuando lo haces todo seguido no dejas que las respuestas a lo que solicitas lleguen.

Al hacerlo con botones o poniendo mensajes en medio, dejas suficiente tiempo para que la respuesta a las acciones que haces llegue.

Esa es la respuesta a tu pregunta.

Si pones una espera de por ejemplo 2 segundos entre acción y acción, seguro que funciona.

Un saludo
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #7  
Antiguo 14-03-2015
Jontart Jontart is offline
Miembro
 
Registrado: jun 2006
Posts: 13
Poder: 0
Jontart Va por buen camino
Perdón por la tardanza, en contestar.

Eso es lo que, en principio, suponía que pasaba, que la página no estaba totalmente cargada. Pero, por ejemplo, no funciona si hago un sleep() de 10 segundos, o un ciclo For muy largo. Sólo funciona si, de alguna manera, salgo del procedimiento que está corriendo, aunque sea por un breve periodo de tiempo (1 segundo, p.e.). Por eso SI que funciona si lo ejecuto desde otro botón, si hago correr un nuevo form durante un tiempo determinado, o si ejecuto un ShowMessage, que es modal.

El programa, ahora, se ejecuta bien; lo que quería saber es porqué. Qué órdenes debo usar para parar totalmente un procedimiento, en el entorno web, hasta obtener la respuesta deseada y que funcione elegantemente.
Código:
while webBrowser2.ReadyState < READYSTATE_INTERACTIVE do 
   Application.ProcessMessages;
¡Ésta no funciona adecuadamente!

Gracias.
Responder Con Cita
  #8  
Antiguo 14-03-2015
Jovalca Jovalca is offline
Miembro
NULL
 
Registrado: sep 2013
Ubicación: Madrid - España
Posts: 30
Poder: 0
Jovalca Va por buen camino
Hola otra vez Jontart.

Hace tiempo que migré a Lazarus y a Mac pero creo recordar que TWebBrowser dispone de un evento OnNavigateComplete o TWebBrowser.OnNavigateComplete2 que puede servirte para lo que necesitas. Inserta las acciones despues del login en ese evento a ver si se soluciona.

Saludos.
Responder Con Cita
  #9  
Antiguo 14-03-2015
Jontart Jontart is offline
Miembro
 
Registrado: jun 2006
Posts: 13
Poder: 0
Jontart Va por buen camino
Si que FUNCIONA.

Utilizando los eventos OnBeforeNavigate(), OnDocumentComplete() y OnNavigateComplete2() se consigue lo que quería sin artificios extraños.

Defino dos variables y creo los eventos:
Código Delphi [-]
var
  Form1: Tform1;
  CurDispatch: IDispatch;
  FDocLoaded: Boolean;

implementation

{$R *.dfm}

procedure TACDM.WebBrowser1BeforeNavigate2(Sender: TObject;
  const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
  Headers: OleVariant; var Cancel: WordBool);
begin
    CurDispatch := nil;
    FDocLoaded := False;
end;

procedure TACDM.WebBrowser1NavigateComplete2(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
   if CurDispatch = nil then
        CurDispatch := pDisp;
end;

procedure TACDM.WebBrowser1DocumentComplete(Sender: TObject;
  const pDisp: IDispatch; var URL: OleVariant);
begin
   if (pDisp = CurDispatch) then  
      begin
        FDocLoaded := True;
        CurDispatch := nil;
      end;
end;
Ahora, en el programa, después de cada acción que requiera una respuesta del servidor pongo:
Código Delphi [-]
   repeat Application.ProcessMessages until FDocLoaded;
y eso es todo.

Gracias por vuestra inestimable ayuda.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Prueba roman La Taberna 0 27-09-2012 20:32:21
Prueba del ratón ArdiIIa Humor 9 05-06-2008 20:13:10
Prueba Archer Humor 5 28-09-2005 22:46:42


La franja horaria es GMT +2. Ahora son las 12:22:44.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi