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 31-10-2006
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Smile Automatización Web (HTTP sin navegador)

¡Hola a todos!

Quisiera saber si alguno de ustedes ha programado algo de automatización Web y qué me aconsejaría para poder implementar ésta en una aplicación Delphi 7 Win32.

Quiero automatizar la operatividad de una página Web, hacer un pequeño robot que:
  1. Acceda a la página.
  2. Ingrese la clave de usuario y contraseña requeridas.
  3. Ingrese a determinada sección del sitio Web.
  4. Envíe al servidor Web el valor de determinados datos que la página solicita (método Post o Get del protocolo HTTP).
  5. Reciba del servidor Web la página o datos resultantes de la consulta.
  6. Extraiga (análisis sintáctico —parse— sobre el stream HTML recibido) los datos relevantes de la consulta (para después almacenarlos en una base de datos).
  7. Repita sucesivamente los pasos 4, 5 y 6 para consultar más información en base a otros valores de entrada (ciclo automático de consulta).

Todo esto sin la necesidad de desplegar la página, es decir, sin utilizar un navegador ni intervención alguna del usuario. Mi aplicación Delphi teniendo comunicación HTTP con el servidor Web de la página.

He visto que hay algunos componentes Delphi que permiten implementar soluciones como la que planteo, incluso he leído que algunos tienen la capacidad de hacer el envío de datos al servidor Web tanto por el método Post como por el método Get, pero me gustaría partir de la experiencia y recomendaciones que amablemente me hagan al respecto.

De antemano muchas gracias.

Un abrazo sin protocolo.

Al González.
Responder Con Cita
  #2  
Antiguo 01-11-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Hola Al, la verdad es que la frase "... pero me gustaría partir de la experiencia ..." impone mucho, sobre todo a los que tenemos poca . Además viniendo la pregunta de quien viene me temo que no es una pregunta de principiante y necesitas respuestas con contenido. Pero por alguna parte habrá que empezar y ya veremos hasta donde llegamos.

Supongo que ya habrás hecho un búsqueda por los foros, ¿has revisados estos hilos?

http://www.clubdelphi.com/foros/showthread.php?t=34263
http://www.clubdelphi.com/foros/showthread.php?t=34666

¿Buscas algo parecido? ¿buscas algo diferente? ¿puede servirte, pero necesitas ampliarlo?

Vamos a ver hasta donde podemos llegar ... A menos que por aquí haya alguien con experiencia que nos de una solución mejor
Responder Con Cita
  #3  
Antiguo 01-11-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Puedes utilizar el componente "TIdHttp" de los "Indy". Es un cliente HTTP que te permitirá requerir un recurso (GET), enviar datos (POST), etc. No tiene nada que ver con el "TWebBrowser", es decir, en ningún momento precisarás mostrar el resultado de tus consultas.

Cuando realizas una petición "GET" puedes obtener el resultado como un sencillo "Stream", no necesitas, por tanto, volcar dicho contenido (sea HTML o sea el que sea) en ningún sitio. Puedes, por tanto, "parsearlo", guardarlo, en fin, lo que necesites.

"Parsers" de HTML hay varios... creo recordar. Será cuestión de que eches un vistazo por Torry's o alguna página similar. Creo que las "Jedi" incluyen algún "parser HTML", por si acaso instalaste estos componentes y no quieres ponerte a buscar ninguno aparte.

No sé si lo que he dicho te sirve como aproximación... acaso algún compañero pueda añadir algo más. Tú ya sabes que puedes replicar lo que te sea menester que por aquí estamos.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #4  
Antiguo 01-11-2006
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
Hola Al.

A la excelente explicación de dec, solamente hará falta añadir que regularmente los sitios manejan una "sesión", cuyo ID guardan en una galleta (cookie) y requieren de este para poder reconocer que usuario ha iniciado sesión y si esta no ha expirado.

Esto también podes manejarlo con las Indy, que cuentan con la maquinaria necesaria para esta tarea: TidCookieManager, que luego asocias a la propiedad CookieManager del ya mencionado TidHTTP.

Finalmente comentar que no hace falta que bajes la página de login cada vez que realices el paso 1/2 de tu explicación. Basta con que realices la llamada -normalmente un POST- que ejecutaría el navegador cuando un usuario humano haga clic en el botón "login", y estes atento a recibir y almacenar (puede ser en memoria) el cookie correspondiente a la sesión.

Claro que esta es la generalidad de los casos, pero puede haber páginas que implementen en reconocimiento del usuario de alguna otra manera, para ellas habrá que hacer algo de análisis de comportamiento, pero siempre son cosas que pueden manejarse desde delphi.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate

Última edición por jachguate fecha: 01-11-2006 a las 02:19:51.
Responder Con Cita
  #5  
Antiguo 01-11-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Bueno, como alternativa a Indy podemos usar Wininet. Podemos hacer Get, podemos hacer Post y maneja las cookies perfectamente incluso las de sesión. No tengo nada en contra de las Indy, es solo por dar alternativas, además no se pueden usar en el Turbo , aunque eso no es culpa suya.

Bueno, un poco de código para animar la cosa:
Código Delphi [-]
uses Windows, SysUtils, Classes,Wininet;

// URL Encode y Decode para codificar los strings segun la norma RFC 1738
function URLEncode(Str: string): string;
var
  i: integer;
begin
  Result:= '';
  for i:= 1 to Length(Str) do
    if Str[i] in ['A'..'Z','a'..'z','0'..'9','-','_','.'] then
      Result:= Result + Str[ i ]
    else
      Result:= Result + '%' + IntToHex(Ord(Str[ i ]),2);
end;

function URLDecode(Str: string): string;
var
  i: integer;
begin
  Result:= '';
  Str:= StringReplace(Str, '+', ' ', [rfReplaceAll]);
  while Length(Str) > 0 do
  begin
    if Copy(Str, 1, 1) = '%' then
    begin
      if not TryStrToInt('$' + Copy(Str, 2, 2),i) then
      begin
        Result:= '';
        Exit;
      end;
      Result:= Result + Char(i);
      Delete(Str, 1, 2);
    end else Result:= Result + Copy(Str, 1, 1);
    Delete(Str,1,1);
  end;
end;

// Con esta funcion hacemos Get y nos devuleve el resultado en un stream
function Get(Url: string; Stream: TStream): Boolean;
var
  hNet: HINTERNET;
  hUrl: HINTERNET;
  Buffer: array[0..10240] of Char;
  BytesRead: Cardinal;
begin
  Result:= FALSE;
  hNet:= InternetOpen('Agente', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hUrl:= InternetOpenUrl(hNet, PChar(Url), nil, 0,
      INTERNET_FLAG_RELOAD, 0);
    if (hUrl <> nil) then
    begin
      while (InternetReadFile(hUrl, @Buffer, sizeof(Buffer), BytesRead)) do
      begin
        if (BytesRead = 0) then
        begin
          Result:= TRUE;
          break;
        end;
        Stream.Write(Buffer,BytesRead);
      end;
      InternetCloseHandle(hUrl);
    end;
    InternetCloseHandle(hNet);
  end;
end;

// Con esta funcion hacemos Post, los campos del formulario se pasan en PostString
// como pares nombre=valor
function Post(Servidor, Pagina: string; Puerto: Word;
  PostStrings: TStringList; Stream: TStream): Boolean;
var
  hNet: HINTERNET;
  hCon: HINTERNET;
  hReq: HINTERNET;
  Context: DWORD;
  Str: string;
  i: integer;
  Buffer: array[0..10240] of Char;
  BytesRead: DWORD;
begin
  Context:= 0;
  Result := FALSE;
  Str:= '';
  hNet := InternetOpen('Agente', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if (hNet <> nil) then
  begin
    hCon:= InternetConnect(hNet,PChar(Servidor),Puerto,nil,nil,
      INTERNET_SERVICE_HTTP,0,Context);
    if (hCon <> nil) then
    begin
      hReq:= HttpOpenRequest(hCon,'POST',PChar(Pagina),nil,nil,nil,
        INTERNET_FLAG_RELOAD,Context);
      if (hReq <> nil) then
      begin
        for i:= 0 to PostStrings.Count - 1 do
        begin
          Str:= Str + '&' + URLEncode(PostStrings.Names[i]) + '=' +
            URLEncode(PostStrings.ValueFromIndex[i]);
        end;
        Delete(Str,1,1);
        try
          if HttpSendRequest(hReq,
            'Content-Type: application/x-www-form-urlencoded',Cardinal(-1),
            PChar(Str),Length(Str)) then
          begin
            while (InternetReadFile(hReq,@Buffer,sizeof(Buffer),BytesRead)) do
            begin
              if (BytesRead = 0) then
              begin
                Result := TRUE;
                break;
              end;
              Stream.Write(Buffer,BytesRead);
            end;
          end;
          except end;
        InternetCloseHandle(hReq);
      end;
      InternetCloseHandle(hCon);
    end;
    InternetCloseHandle(hNet);
  end;
end;

Ahora que ya podemos hacer Get y Post solo nos falta analizar las paginas que obtenemos ¿voy por buen camino?

EDITO:
Modifico la función Post para incluir la cabecera Content-Type, que al parecer es necesaria, al menos para el siguiente ejemplo:

Entrar al ClubDelphi, iniciar sesión y obtener la pagina principal de los foros:
Código Delphi [-]
procedure Ejemplo;
var
  Campos: TStringlist;
  Stream: TMemoryStream;
begin
  Campos:= TStringList.Create;
  Stream:= TMemoryStream.Create;
  try
    Campos.Values['vb_login_username']:= 'usuario';
    Campos.Values['vb_login_password']:= 'password';
    Campos.Values['submit']:= 'Ingresar';
    Campos.Values['s']:= '';
    Campos.Values['do']:= 'login';   
    Post('www.clubdelphi.com','/foros/login.php',80,Campos,Stream);
    Stream.Clear;
    Get('http://www.clubdelphi.com/foros/',Stream);
    Stream.SaveToFile('d:\1.txt');
  finally
    Campos.Free;
    Stream.Free;
  end;
end;

Última edición por seoane fecha: 02-11-2006 a las 20:32:34.
Responder Con Cita
  #6  
Antiguo 01-11-2006
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Smile

¡Hola a todos!

Gracias Seoane, David y Antonio por la información que me proporcionan. Este viernes evaluaré sus sugerencias y haré las primeras pruebas. Los mantendré informados de mis avances para que el curso de esta solución (el hilo en sí) sea una experiencia de la que puedan aprender otros desarrolladores que se encuentren en la misma vicisitud.

Un abrazo telarañudo.

Al González.
Responder Con Cita
  #7  
Antiguo 01-11-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Empezado por Domingo
¿voy por buen camino?
Pues yo creo que sí, vamos. Está muy bien Seoane.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #8  
Antiguo 01-11-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Román, personalmente también pienso que utilizar las Indy puede ser más razonable, empero, estarás conmigo en que el código fuente es una maravilla, que acaso en ocasiones sea mejor (en varios aspectos y por diversos motivos) utilizar, directamente, el API WinInet. Yo desde luego me he permitido añadir el código entre el resto de Trucos, con el permiso de Seoane, pues que creo que puede ser un código fuente muy útil.

Ahora, ¿que por eso digo que las Indy no debieran usarse? Nada de eso, de hecho ya he dicho que me parece más razonable usarlas, siempre que sea posible; pero también digo que no viene de más tener otras opciones, que ratón que conoce un agujero sólo pronto le caza el gato (o algo así).

¿Que no?
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #9  
Antiguo 01-11-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Estoy de acuerdo contigo Román. Más ahora que sé que puede funcionar mejor incluso. Empero, lo dicho dicho, una cosa no quita la otra. En realidad creo que estamos de acuerdo todos, incluído el propio Domingo.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #10  
Antiguo 04-05-2013
pedrolazarus pedrolazarus is offline
Miembro
NULL
 
Registrado: sep 2012
Posts: 91
Poder: 12
pedrolazarus Va por buen camino
Smile

Cita:
Empezado por seoane Ver Mensaje
Bueno, como alternativa a Indy podemos usar Wininet. Podemos hacer Get, podemos hacer Post y maneja las cookies perfectamente incluso las de sesión. No tengo nada en contra de las Indy, es solo por dar alternativas, además no se pueden usar en el Turbo , aunque eso no es culpa suya.

Bueno, un poco de código para animar la cosa:

Y se formo la fiesta

Exelente aporte para lo que no tienen instalado el componente indy sobre todo en lazarus
Responder Con Cita
  #11  
Antiguo 12-02-2008
jobequ jobequ is offline
Registrado
 
Registrado: feb 2008
Posts: 1
Poder: 0
jobequ Va por buen camino
Ayuda!!!!

Buenas tardes.. Amigos soy nuevo en este sitio y para serles sincero no creo tener ni la mitad del conocimiento q tienen ustedes y por eso les pido su ayuda.. Resulta que aqui en venezuela para poder solicitar la cita del pasaporte es necesario ingresar a esta pag: http://www.onidex.com.ve/ pero el servicio brindado por esta pagina es fatal, osea no sirve.. (NO PUEDO CONECTARME CON FACILIDAD) El servicio de la pagina es todo el dia pero las solicitudes se acaban en menos de media hora a partir de las 9 am. Lo que quisiera yo es q me ayuden a poder automatizar la entrada a la pagina sin tener que estar dandole reintentar todo el tiempo y tambien a poder llenar todo lo q pide la pag de forma automatica con agun programa o algo.. Les repito no se mucho en relacion a esto pero puedo aprender.. Espero pronta respuesta y de antemano muchas gracias.. (Para su mayor comodidad puenen in gresar a la pag despues de las 11 am hora venezuela)
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
Automatizacion de word (generar documentos) alt126 C++ Builder 4 24-04-2007 04:19:27
Automatizacion de word (insertar tablas) alt126 C++ Builder 2 04-11-2005 10:44:29
Consejo Automatizacion Excel Builder C++ alt126 C++ Builder 0 14-04-2005 10:52:04
HTTP Indy bochi Internet 1 27-12-2003 01:57:34
Http Server ebeltete Internet 0 17-05-2003 02:57:39


La franja horaria es GMT +2. Ahora son las 13:38:29.


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