PDA

Ver la Versión Completa : Manejar diálogo de Internet explorer


lpedrazzi
13-11-2006, 21:25:53
Buenas a todos...la cuestión es la siguiente tengo una aplicación desarrollada en Delphi 6, cuyo fin es automatizar la descarga de archivos mediante un WebBrowser, la pregunta es la siguiente cuando se abre el diálogo de la descarga de archivos tengo forma de simular el click en el botón Guardar?

dec
13-11-2006, 21:29:44
Hola,

¿Y cuál es el motivo de usar un "WebBrowser" para esa tarea? Lo digo porque con un componente "IdHttp", por poner un caso, podrías acceder a recursos en Internet y descargarlos sin intervención alguna del usuario... Pienso además que aunque consiguieras "hacer clic" en el correspondiente botón, todavía no podrías saber, por ejemplo, cuándo terminó de descargarse cierto archivo, si hubo problemas en su descarga, etc., etc.

Bueno. Nada es imposible, pero, tengo esa curiosidad, ¿porqué usar un "WebBrowser"?

roman
13-11-2006, 21:30:03
¿Y cuál es la finalidad de usar el WebBrowser? ¿Por que no usas las componentes Indy, en específico la TIdHTTP, que te permite interactuar con un servidor sin el "estorbo" de la interfaz que supone algo como el WebBrowser?

// Saludos

dec
13-11-2006, 21:31:03
Hola,

Telepatía. A eso se le llama telepatía, por lo menos. :D :D :D

En el mismo minuto, señores, sin previo acuerdo ni nada. :D :D

roman
13-11-2006, 21:31:09
¡Válgame! Dijimos prácticamente lo mismo :)

// Saludos

seoane
13-11-2006, 21:33:31
Hola,

Telepatía. A eso se le llama telepatía, por lo menos. :D :D :D



:D A eso se le llama Eco

dec
13-11-2006, 21:36:32
Hola,

Bueno. Yo intuyo que el compañero quiere presentar al usuario una lista de enlaces. En un "WebBrowser". Pudiera hacerse de otro modo, pero, si se tratara de esto que digo, lo que acaso podría hacerse es presentar al usuario un "WebBrowser", de acuerdo, pero, "interceptar" cuando el usuario hace "clic" en una determinada URL, de manera que "cancelemos" el comportamiento del "WebBrowser" y comenzemos la descarga del archivo utilizando el componente que se considere oportuno, por ejemplo, el mencionado "IdHttp".

No sé. El compañero tendrá que decir algo y aun algos también. :)

lpedrazzi
13-11-2006, 21:38:39
Estuve usando idhttp pero cuando llego al link no esta directamente el archivo para descargar por ej http://www.sitioweb.com/archivo.zip sino que solo tengo la url donde estaria el archivo ej: http://www.sitioweb.com/nn?cmd=download&num=12941&prod=4 probe con urlmon y descarga cualquier cosa.

dec
13-11-2006, 21:41:01
Hola,

No debería haber problema en ese sentido con el componente "IdHttp". Es decir, al componente le da igual que el archivo esté en la URL "http://www.pepe.com?archivo=322", siempre que esa URL al cabo lleve al recurso que nos interesa. Si al cabo esta última URL retorna el archivo que te interesa descargar, el componente "IdHttp" lo descargará sin problemas. Vamos, o estoy completamente equivocado, que me parece que no, en este caso, pero, todo puede ser. :)

roman
13-11-2006, 21:43:10
El sitio web en cuestión, ¿requiere algún tipo de autenticación? Hace poco se comentó esto ya que tales sitios suelen manejar una cookie y tu coomponente IdHttp deb poder procesarla.

// Saludos

seoane
13-11-2006, 21:43:31
Puede que el problema no sea la dirección si no la Sesión o las Cookies. Si copias y pegas directamente esa dirección en un navegador ¿puedes bajar el archivo?, o por el contrario necesitas abrir primero otra pagina para poder acceder a la descarga del archivo. Si es así, date una vuelta por el hilo de Automatización Web (http://www.clubdelphi.com/foros/showthread.php?t=37050) del compañero Al, donde intentamos hacer algo parecido

roman
13-11-2006, 21:45:22
Bueno, peroooo... esta telepatía :D

lpedrazzi
13-11-2006, 21:49:57
si copio y pego esa direccion me da un error por eso usé anteriormente idhttp con el método post poniendo usuario y contraseña, pero aparentemente cuando se ejecuta el post no me devuelve la pagina en donde están dichos enlaces...

seoane
13-11-2006, 22:00:58
Si ya hablamos de temas de autenticación reitero mi propuesta de que leas el post sobre Automatización Web, allí encontraras consejos sobre como utilizar el componente IdHttp para que acepte cookies, redirecciones, etc. Tampoco dices que te esta devolviendo, solo dices que no es lo que tu esperabas pero seria interesante si se trata por ejemplo de algún mensaje de error.

Y por ultimo te recomiendo una herramienta que te puede ser muy útil

http://www.fiddlertool.com/fiddler/

con ella podrás echarle un vistazo a la comunicación entre el explorador y la pagina que te interesa y asi saber mejor como reproducirlo.

roman
13-11-2006, 22:17:32
Mira a ver si te sirve esta función que hice:


(**
* Descarga un recurso http
*
* @param Url - recurso a descargar
* @param UrlInicio - url de la página para iniciar sesión
* @param Usuario, Password - usuario y contraseña para autenticación
* @param Contenido - Stream que recibe los datos, debe estar ya creado.
*)
procedure Descargar(const Url, UrlInicio, Usuario, Nip: String; Contenido: TStream);
var
IdHttp: TIdHttp;
Campos: TStringList;

begin
IdHttp := TIdHttp.Create;
Campos := TStringList.Create;

try
IdHttp.HandleRedirects := true;
IdHttp.AllowCookies := true;
IdHttp.HTTPOptions := IdHttp.HTTPOptions + [hoForceEncodeParams];

Campos.Values['usuario'] := Usuario;
Campos.Values['nip'] := Nip;

IdHttp.Post(UrlInicio, Campos);

IdHttp.Get(Url, Contenido);
Contenido.Position := 0;

finally
IdHttp.Free;
Campos.Free;
end;
end;


// Saludos

lpedrazzi
14-11-2006, 14:08:26
Muchas gracias comienzo a probar y te comento.

seoane
14-11-2006, 15:36:57
Quisiera saber si sabes de que se trata este valor que me devuelve
SESSIONID=amXCdPaluGH4s29AL7.. sera la cookie session para validar el login?


Exactamente esa cookie se utiliza para identificar la sesión. La cosa funciona así, la primera vez que acedes a la pagina, este te devuelve la cookie con un identificador. Tu navegador cada vez que accedes a esa misma pagina o a otra del mismo sitio, manda esa cookie, de esa forma el servidor puede rastrear la sesión. Si cierras el navegador y vuelves a acceder a la pagina, el servidor mandara un identificador diferente para identificar la nueva sesión.

Ahora pensemos en un ejemplo. Accedemos a la pagina de login, entonces recibimos una cookie con el identificador de sesión. Enviamos el nombre de usuario y contraseña por POST, y también enviamos la cookie. Ahora estamos identificados en esa sesión, de esta forma cada vez que accedamos a una pagina en ese servidor en esa misma sesión el servidor sabrá que estamos logueados.

Esto puede parecer complicado, pero es tan simple como decirle idHttp que acepte cookies, o usar Wininet. Ellos se encargaran de manejar las cookies sin que tengas tu que hacer nada.

lpedrazzi
14-11-2006, 20:04:58
Exactamente esa cookie se utiliza para identificar la sesión. La cosa funciona así, la primera vez que acedes a la pagina, este te devuelve la cookie con un identificador. Tu navegador cada vez que accedes a esa misma pagina o a otra del mismo sitio, manda esa cookie, de esa forma el servidor puede rastrear la sesión. Si cierras el navegador y vuelves a acceder a la pagina, el servidor mandara un identificador diferente para identificar la nueva sesión.

Ahora pensemos en un ejemplo. Accedemos a la pagina de login, entonces recibimos una cookie con el identificador de sesión. Enviamos el nombre de usuario y contraseña por POST, y también enviamos la cookie. Ahora estamos identificados en esa sesión, de esta forma cada vez que accedamos a una pagina en ese servidor en esa misma sesión el servidor sabrá que estamos logueados.

Esto puede parecer complicado, pero es tan simple como decirle idHttp que acepte cookies, o usar Wininet. Ellos se encargaran de manejar las cookies sin que tengas tu que hacer nada.


Amigo aqui esta el pedacito e código que estoy intentando implementar sin conseguir resultados positivos aun, he puesto las propiedades en true del idhttp1 para haceptar las cookies, me parece que ahora estoy fallando en lo que envío en el post, el action de la etiqueta del form dice action="/md" method="post" como debería armar el post...en el fiddler me figura

http://www.alfabeta.net/md-downloads.xtp?cmd=perfil&umdat=miusuario


var
datosPost: TIdMultiPartFormDataStream;
begin
datosPost := TIdMultiPartFormDataStream.Create;
try
datosPost.AddFormField('cmd', 'login');
datosPost.AddFormField('stylesheet', 'md.xls');
datosPost.AddFormField('Usuario', 'mi_usuario');
datosPost.AddFormField('pwd', 'mi_contraseña');
datosPost.AddFormField('x', '0');
datosPost.AddFormField('y', '0');
try
idhttp1.AllowCookies := true;
idHttp1.Request.Referer := 'http://www.alfabeta.net/md.xtp';
memo1.Clear;
memo1.lines.Add(idHttp1.Post('http://www.alfabeta.net/md.xtp', datosPost));
finally
idHttp1.Free;
end;
finally
datosPost.Free;
end;

roman
14-11-2006, 20:17:54
No entiendo. El código que muestras sólo maneja la parte del login, ¿en qué momento haces la petición del archivo?

¿Probaste la función que puse?

// Saludos

lpedrazzi
14-11-2006, 20:47:32
No entiendo. El código que muestras sólo maneja la parte del login, ¿en qué momento haces la petición del archivo?

¿Probaste la función que puse?

// Saludos

El problema es que todavía no puedo pasar del login, en teoría una vez ya iniciada la sesion me mostraría los links para descargar dichos archivos. En cuanto a la funcion me dice que el stream lo tengo que tener creado pero me salta un error con el stream me dice que no puse el seek.

asi estoy haciendo el llamado..


procedure TForm1.Button3Click(Sender: TObject);
var
Contenido:TStream;
begin
Descargar('http://www.alfabeta.net/md.xtp','http://www.alfabeta.net','mi_usuario','mi_pass',Contenido);
end;

lpedrazzi
14-11-2006, 22:30:11
Gente gracias a todos por su aporte la verdad es que estoy aprendiendo un montón, les comento que felizmente he podido acceder a dicho contenido la cuestion estaba en que al realizar el post me devolvia "HTTP/1.1 302 Found" Gracias seoane por brindarme la herramienta Fiddler y los conocimientos basicos de HTTP, Gracias tambien a Román por la funcion aportada, fue de mucha utilidad, solo me faltaría un detalle. El archivo que intento descargar en el idHttp1.get es un zip como hago para sacarlo del stream?, pongo el código para que vean como resolví junto a uds. el tema.

procedure TForm1.Button1Click(Sender: TObject);
var
IdHttp: TIdHttp;
Campos: TStringList;
Url, UrlInicio, Usuario, Nip: String;
Contenido: TStringStream;
begin
Campos := TStringList.Create;
try
Contenido := TStringStream.Create('');
IdHttp1.HandleRedirects := true;
IdHttp1.AllowCookies := true;
IdHttp1.HTTPOptions := IdHttp1.HTTPOptions + [hoForceEncodeParams];
UrlInicio:='http://www.alfabeta.net/md.xtp';
Campos.Values['cmd'] := 'login';
Campos.Values['stylesheet'] := 'md.xls';
Campos.Values['usuario'] := 'mi_usuario';
Campos.Values['pwd'] := 'mi_pass';
Campos.Values['y'] := '0';
Campos.Values['x'] := '0';

IdHttp1.Post(UrlInicio, Campos);
UrlInicio:='http://www.alfabeta.net/md?cmd=login&stylesheet=md.xsl&usuario=mi_usuario&pwd=mi:pass&x=0&y=0';
memo1.Clear;
memo1.Lines.Add(IdHttp1.Post(UrlInicio, Campos));
Url:='http://www.alfabeta.net/md?cmd=download&numero=12945&producto=4';
IdHttp1.Get(Url, Contenido);
Contenido.Position := 0;
finally
IdHttp1.Free;
Campos.Free;
end;
end;

seoane
14-11-2006, 22:49:28
Para empezar podemos usar un TMemoryStream en vez de un TStringStream, es decir:

...

Contenido: TMemoryStream;
begin

...

Contenido := TMemoryStream.Create;


Para guardarlo solo tendríamos que hacer algo como esto:

Contenido.SaveToFile('c:\1.zip');

lpedrazzi
14-11-2006, 23:04:48
GRACIASSSSS!!!!! seoane SOS UN M A E S T R O!!!