Ver Mensaje Individual
  #25  
Antiguo 15-12-2006
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Reputación: 30
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 A jíjole, ya es tarde

¡Hola a todos!

Cita:
Empezado por seoane
...Aprovecho para preguntar ¿que le paso a este hilo? ¿se puede considerar muerto? ¿nadie mas saco algo en limpio?...
Hace unos minutos me dije: «voy a revisar el correo mientras Pepe realiza esas últimas pruebas» y entonces descubro esta pregunta de Domingo.

Mañana instalaremos la primera versión de la solución a nuestro cliente. Ya es funcional la automatización sobre dos de los tres sitios Web (en una versión básica). Faltará hacer algunas mejoras, pero confío en que pronto tendremos esto al 100%.

Algunos datos clave para quienes deseen desarrollar este tipo de soluciones:

El componente TIdHTTP es excelente, pero no es la única herramienta que utilizamos. En cada caso primero hay que estudiar las tripas del sitio Web, elaborando un "mapa" de las URLs que se mandan llamar y sus parámetros. Un largo trabajo de arqueología informática, donde se requiere mucha paciencia. En este punto, mi recomendación es usar un componente TWebBrowser para saber cuáles son los parámetros que la página envía al servidor Web, y entonces después poder automatizar esos envíos con TIdHTTP. Domingo Seoane nos expone un buen ejemplo del evento TWebBrowser.OnBeforeNavigate2 en este mensaje.

(la sentencia "ShowMessage(Values['P1']);" puede ser sustituida por "ShowMessage(Text);" para mostrar todos los parámetros (nombres y valores) que están a punto de enviarse en la petición).

Gracias Domingo, ese ejemplo me sirvió muchísimo cuando no encontraba la manera de ver los parámetros que una página enviaba bajo el método Post. Lo que usualmente hacía para averiguarlo era guardar una copia local de la página como archivo .htm, cambiar su método Post por Get y ejecutar tal archivo, pero por alguna razón no se guardaba correctamente (incluso hasta instalé Firefox por primera vez para intentarlo con ese otro navegador ). Pero definitivamente es más profesional hacer trabajo de arqueología con herramientas más finas y no puro pico y pala.

La esencia de automatizar un sitio Web ya sea con TIdHTTP o con rutinas de más bajo (y flexible) nivel como las propuestas por Domingo, consiste en conocer las URLs (direcciones Web) a las cuales hay que ordenarles algo y los parámetros que habremos de enviarles para que ese algo ocurra de manera correcta. Dichas URLs aparecen en los atributos "Action" de las etiquetas HTML "Forms" (¿cómo? ¿el lector todavía no ha usado la opción "Ver código fuente" de su navegador? ).

Generalmente, cuando se invoca a una de esas direcciones Web, el misterioso programa servidor que se encuentra del otro lado de la línea (generalmente Apache), nos envía como respuesta un flujo de bytes HTML, una página vaya. El resto del trabajo consiste en analizar ese flujo de bytes como una cadena de caracteres, buscando en posiciones específicas el dato que deseamos extraer.

Esto no quiere decir que vamos a estudiar la cadena que regresó byte por byte. La cadena de bytes puede ser guardada como una página .htm y verla con mayor detalle en cualquier editor de texto. De hecho esto se hace generalmente desde antes de empezar a programar (me meto al navegador, consulto un dato y la página que me regresa la guardo como archivo local). Se estudia ese archivo de texto para encontrar patrones comunes que ayuden a identificar con seguridad la posición donde siempre aparece el dato que buscamos. Es decir, ya se ha familiarizado uno con el código fuente de una página de resultados y es entonces cuando podemos escribir un algoritmo que acaricie a esos caracteres y bese a la parte más sensible de la cadena, obteniendo ese «¡Si, aquí!» que todos deseamos escuchar.

Código Delphi [-]
    { Primera fila de datos es el último producto consultado de la
      cotización }
    I := Pos ('dp[1]=new Prt(', Respuesta);

    If I = 0 Then
      Exit;

    Contador := 0;

    For I := I + 14 To MaxInt Do
      If Respuesta [i] = ',' Then
      Begin
        Inc (Contador);

        { Después de la tercera coma está el valor para el parámetro "whs"
          usado en la consulta de disponibilidad }
        If Contador = 3 Then
        Begin
          ParametroWhs := Copy (Respuesta, I + 2,
            PosEx ('''', Respuesta, I + 2) - (I + 2));
        End
          Else
          { Después de la octava coma está el precio }
          If Contador = 8 Then
          Begin
            Precio := ValorNumerico (Copy (Respuesta, I + 2,
              PosEx ('''', Respuesta, I + 2) - (I + 2)));
          End
          Else
            { Después de la vigésima coma está el valor para el parámetro
              "invtid" usado en la consulta de disponibilidad }
            If Contador = 20 Then
            Begin
              ParametroInvtid := Copy (Respuesta, I + 2,
                PosEx ('''', Respuesta, I + 2) - (I + 2));
              Break;
            End;
      End;

En las próximas versiones vamos a utilizar alguna biblioteca (esas que creíamos que eran librerías en el siglo pasado) especial para análisis sintáctico HTML y reconocimiento de expresiones regulares. Esto con el fin de hacer más segura la extracción de datos. Porque como el propietario del sitio cambie ligeramente el diseño de la página...¡pabernosmatao!

Todo esto que escribí fue a botepronto (palabra hermana de pabernosmatao) y en base a mis escasos conocimientos sobre la Web. Aún así, espero que resulte de utilidad y de antemano pido disculpas por si dije alguna babosada.

Ahora sí me voy a cenar, mañana será al gran día (a ver cómo me sale la quincena ).

Un abrazo parseado.
Responder Con Cita