Page 1 of 5

Capturar pagina html y recuperar resultado

Posted: Thu Aug 22, 2024 10:35 pm
by leandro
Hola buenas tardes para todos, no se si esto se pueda hacer con FW y la nueva clase WebView2 o con otra.

Necesitamos recuperar la información de una pagina, luego de ingresar un dato en un get (input), hacer clic (debe ser desatendido) en un botón para hacer otra consulta y luego si recuperar el resultado en html, para ser almacenado en variables del lado de FW.

Paso 1 - Ingresar a la página
https://muisca.dian.gov.co/WebRutMuisca ... oRUT.faces
Paso 2 - Completar el dato con el numero de identificación
Paso 3 - Hacer clic en el botón "Buscar"

Image

Paso 4 - Guardar en variables el contenido de las etiquetas con el resultado.

Image

De antemano gracias :D

De antemano gracias

Re: Capturar pagina html y recuperar resultado

Posted: Fri Aug 23, 2024 5:41 am
by Antonio Linares
Estimado Leandro,

Se puede hacer con webview inyectando código javascript

Voy a probar a hacerlo y te comento

Re: Capturar pagina html y recuperar resultado

Posted: Fri Aug 23, 2024 9:52 am
by Antonio Linares
1. Le pido a Claude ayuda. Le he pasado tu pregunta y le sugiero inyectar codigo javascript desde webview y me reponde lo siguiente:

Entiendo que necesitas automatizar un proceso de consulta en una página web de la DIAN (Dirección de Impuestos y Aduanas Nacionales de Colombia) utilizando un WebView. Vamos a desglosar el proceso y crear un script que pueda realizar estas acciones de forma desatendida.

Para lograr esto, podemos usar JavaScript para interactuar con la página web dentro del WebView. Aquí te presento una solución paso a paso:

Para implementar esta solución en tu aplicación con WebView, necesitarás seguir estos pasos:

1. Configura un WebView en tu aplicación

2. Carga la URL de la DIAN en el WebView:

https://muisca.dian.gov.co/WebRutMuisca ... oRUT.faces

3. Una vez que la página esté cargada, inyecta y ejecuta el script JavaScript proporcionado.

4. Desde el código nativo de tu aplicación, llama a la función realizarConsultaDIAN pasando el número de identificación como argumento.

4. Implementa un método en tu código nativo para recibir el resultado del WebView

Y propone este código:

Code: Select all | Expand

// Función para realizar la consulta
function realizarConsultaDIAN(numeroIdentificacion) {
    // Esperar a que la página se cargue completamente
    document.addEventListener('DOMContentLoaded', function() {
        // Paso 2: Completar el dato con el número de identificación
        var inputNIT = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit');
        if (inputNIT) {
            inputNIT.value = numeroIdentificacion;
        } else {
            console.error('No se encontró el campo de entrada para el NIT');
            return;
        }

        // Paso 3: Hacer clic en el botón "Buscar"
        var botonBuscar = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:btnBuscar');
        if (botonBuscar) {
            botonBuscar.click();
        } else {
            console.error('No se encontró el botón de búsqueda');
            return;
        }

        // Esperar a que se carguen los resultados
        setTimeout(function() {
            // Recuperar el resultado en HTML
            var resultadoHTML = document.querySelector('.resultado').innerHTML;
            
            // Aquí puedes procesar el resultadoHTML como necesites
            console.log('Resultado obtenido:', resultadoHTML);
            
            // Enviar el resultado al código nativo (depende de tu implementación específica)
            if (window.Android) {
                // Para Android
                window.Android.recibirResultado(resultadoHTML);
            } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.recibirResultado) {
                // Para iOS
                window.webkit.messageHandlers.recibirResultado.postMessage(resultadoHTML);
            }
        }, 2000); // Ajusta este tiempo según sea necesario
    });
}

// Llamada a la función (esto se haría desde el código nativo)
// realizarConsultaDIAN('123456789');
El asume que vamos a usar Android ó iOS, pero lo vamos a adaptar para usar FWH. Continuamos...

Re: Capturar pagina html y recuperar resultado

Posted: Fri Aug 23, 2024 1:09 pm
by Antonio Linares
Primer intento. Falta recoger los datos mostrados:

Code: Select all | Expand

#include "FiveWin.ch"

static oWebView

function Main()

   local oWnd

   DEFINE WINDOW oWnd TITLE "Usando DIAN desde un webview" SIZE 1050, 700
    
   oWebView = TWebView2():New( oWnd )

   oWebView:Navigate( "https://muisca.dian.gov.co/WebRutMuisca/DefConsultaEstadoRUT.faces" )
   // SysWait( 3 )
   oWebView:InjectJavascript( JavaScript() )
   // oWebView:OpenDevToolsWindow()
   oWebView:Eval( "consultaDIAN( '79760202' )" )

   ACTIVATE WINDOW oWnd CENTER ;
      ON RESIZE oWebView:SetSize( nWidth, nHeight )

   oWebView:End()

return nil

function Javascript()

   local cCode 

   TEXT INTO cCode 
      function consultaDIAN( numeroIdentificacion ) 
      {
         var inputNIT = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit');
         if (inputNIT) {
            inputNIT.value = numeroIdentificacion;
         } else {
            console.error('No se encontró el campo de entrada para el NIT');
            return;
         }     
         
         var botonBuscar = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:btnBuscar');
         if (botonBuscar) {
            botonBuscar.click();
         } else {
            console.error('No se encontró el botón de búsqueda');
            return;
         }
      }
   ENDTEXT

return cCode

Re: Capturar pagina html y recuperar resultado

Posted: Fri Aug 23, 2024 6:36 pm
by leandro
Antonio buenas tardes como estas?

Intentamos compilar el código que nos enviaste, pero no esta devolviendo este error. Lo estamos compilando con la versión FWH2404 - xHarbour 1.3.1 Intl. (SimpLex) (Build 20240108) - BCC770

Code: Select all | Expand

Application
===========
   Path and name: C:\fwh2404\samples\leandro.exe (32 bits)
   Size: 3,763,712 bytes
   Compiler version: xHarbour 1.3.1 Intl. (SimpLex) (Build 20240108)
   FiveWin  version: FWH 24.04
   C compiler version: Borland/Embarcadero C++ 7.7 (32-bit)
   Windows 8 64 Bits, version: 6.2, Build 9200 

   Time from start: 0 hours 0 mins 0 secs 
   Error occurred at: 08/23/24, 13:31:13
   Error description: Warning BASE/1004  Message not found: TWEBVIEW2:INJECTJAVASCRIPT

Stack Calls
===========
   Called from: source\rtl\tobject.prg => TWEBVIEW2:ERROR( 0 )
   Called from: source\rtl\tobject.prg => TWEBVIEW2:MSGNOTFOUND( 0 )
   Called from: source\rtl\tobject.prg => TWEBVIEW2:INJECTJAVASCRIPT( 0 )
   Called from: leandro.prg => MAIN( 15 )

System
======
   CPU type: 12th Gen Intel(R) Core(TM) i7-12700 2112 Mhz
   Hardware memory: 32510 megs

   Free System resources: 90 %
        GDI    resources: 90 %
        User   resources: 90 %

   Windows total applications running: 1
      1 ,                                                                                                     

Variables in use
================
   Procedure     Type   Value
   ==========================
   TWEBVIEW2:ERROR
     Param   1:    C    "Message not found"
     Param   2:    C    "TWEBVIEW2"
     Param   3:    C    "INJECTJAVASCRIPT"
     Param   4:    N    1004
     Local   1:    U    
     Local   2:    O    Class: TWEBVIEW2
     Local   3:    N    13
   TWEBVIEW2:MSGNOTFOUND
     Param   1:    C    "INJECTJAVASCRIPT"
     Param   2:    O    Class: TWEBVIEW2
   TWEBVIEW2:INJECTJAVASCRIPT
     Param   1:    C    "      function consultaDIAN( numeroIdentificacion )      {         var inputNIT = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit');         if (inputNIT) {            inputNIT.value = numeroIdentificacion;         } else {            console.error('No se encontró el campo de entrada para el NIT');            return;         }                      var botonBuscar = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:btnBuscar');         if (botonBuscar) {            botonBuscar.click();         } else {            console.error('No se encontró el botón de búsqueda');            return;         }      }"
   MAIN
     Local   1:    O    Class: TWINDOW

Linked RDDs
===========
   DBF
   DBFFPT
   DBFBLOB
   DBFNTX

DataBases in use
================

Classes in use:
===============
     1 ERROR
     2 HASHENTRY
     3 HBCLASS
     4 HBOBJECT
     5 TWINDOW
     6 TBRUSH
     7 TFONT
     8 TREG32
     9 TWEBVIEW2
    10 TSTRUCT

Memory Analysis
===============
      642 Static variables

   Dynamic memory consume:
      Actual  Value:          0 bytes
      Highest Value:          0 bytes

Re: Capturar pagina html y recuperar resultado

Posted: Sat Aug 24, 2024 5:32 am
by Antonio Linares
Leandro,

Hace falta una versión actualizada de la Clase TWebView2

Tan pronto como esté terminado te envío las nuevas librerias de FWH para que lo puedas construir

Re: Capturar pagina html y recuperar resultado

Posted: Mon Aug 26, 2024 7:27 pm
by Antonio Linares
Recuperando los datos correctamente usando la nueva Clase TWebView2:

Code: Select all | Expand

#include "FiveWin.ch"

static oWebView

function Main()

   local oWnd, cResult

   TEXT INTO cResult 
      [ document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:primerNombre' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:otrosNombres' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:primerApellido' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:segundoApellido' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:estado' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:dv' ).innerHTML ] 
   ENDTEXT     

   DEFINE WINDOW oWnd TITLE "Usando DIAN desde un webview" SIZE 1050, 700
    
   oWebView = TWebView2():New( oWnd )
   oWebView:bOnNavigationCompleted = { | cUrl, hWebView | If( "sessionid" $ cUrl, oWebView:Eval( cResult ),) }

   oWebView:Navigate( "https://muisca.dian.gov.co/WebRutMuisca/DefConsultaEstadoRUT.faces" )
   oWebView:InjectJavascript( JavaScript() )
   // oWebView:OpenDevToolsWindow()
   oWebView:bOnEval = { | cJson, hWebView | If( cJson != "null" .and. cJson != "{}", MsgInfo( cJson ),) }
   oWebView:Eval( "consultaDIAN( '79760202' )" )

   ACTIVATE WINDOW oWnd CENTER ;
      ON RESIZE oWebView:SetSize( nWidth, nHeight )

   oWebView:End()

return nil

function Javascript()

   local cCode 

   TEXT INTO cCode 
      function consultaDIAN( numeroIdentificacion ) 
      {
         var inputNIT = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit');
         if (inputNIT) {
            inputNIT.value = numeroIdentificacion;
         } else {
            console.error('No se encontró el campo de entrada para el NIT');
            return;
         }     
         
         var botonBuscar = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:btnBuscar');
         if (botonBuscar) {
            botonBuscar.click();
         } else {
            console.error('No se encontró el botón de búsqueda');
            return;
         }
      }
   ENDTEXT

return cCode
Image

Re: Capturar pagina html y recuperar resultado

Posted: Mon Aug 26, 2024 7:32 pm
by Antonio Linares
Lo próximo sería ocultar la ventana y el webview para que no se vea como se obtiene la información :-)

Re: Capturar pagina html y recuperar resultado

Posted: Tue Aug 27, 2024 4:16 pm
by leandro
Excelente Antonio funciono de maravilla :D :D :D :D :D
Ahora nos falta el paso final :oops: :oops: :oops:
Como se hace para ocultar la ventana? y hacer el proceso sin que el usuario se de cuenta?

Por otro lado queremos entender el funcionamiento y el orden en que se ejecuta el proceso del lado del navegador y en que momento del lado de FW.

Code: Select all | Expand

DEFINE WINDOW oWnd TITLE "Usando DIAN desde un webview" SIZE 1050, 700
   
   oWebView = TWebView2():New( oWnd )

   //TERCER PASO - Cuando se haya cargado la pagina por completo evaluamos la cadena cResult para que guarde en un array los datos que estan en los inputs
   //Lo que no entiendo es esta sintaxis [b]If( "sessionid" $ cUrl [/b], de donde recuperamos ese sessionid y para que sirve el signo $
   oWebView:bOnNavigationCompleted = { | cUrl, hWebView | If( "sessionid" $ cUrl, oWebView:Eval( cResult ),) }

   //PRIMER PASO - Hacemos el llamado a la url
   oWebView:Navigate( "https://muisca.dian.gov.co/WebRutMuisca/DefConsultaEstadoRUT.faces" )
   //SEGUNDO PASO - Le inyectamos el código java script al navegador "webview"
   oWebView:InjectJavascript( JavaScript() )
   //CUARTO PASO - Definimos el codeblock bOnEval, para ejecutar la acción que necesitamos hacer de lado del FW, lo que no entiendo es en que momento se llena la variable cJson
   oWebView:bOnEval = { | cJson, hWebView | If( cJson != "null" .and. cJson != "{}", MsgInfo( cJson ),) }
   //QUINTO PASO - Evaluamos la función en javascript del lado del navegador que habíamos inyectado consultaDIAN la cual se encarga de ingresar el dato a buscar y hacer clic en el botón para busqueda.
   oWebView:Eval( "consultaDIAN( '79760202' )" )

   ACTIVATE WINDOW oWnd CENTER ;
      ON RESIZE oWebView:SetSize( nWidth, nHeight )
 
Si es ese el orden?

Gracias de antemano.

Re: Capturar pagina html y recuperar resultado

Posted: Wed Aug 28, 2024 12:23 pm
by Antonio Linares
Esta versión casi que oculta todo el proceso:

Code: Select all | Expand

#include "FiveWin.ch"

static oWebView

function Main()

   local oWnd, cResult

   TEXT INTO cResult 
      [ document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:primerNombre' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:otrosNombres' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:primerApellido' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:segundoApellido' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:estado' ).innerHTML,
        document.getElementById( 'vistaConsultaEstadoRUT:formConsultaEstadoRUT:dv' ).innerHTML ] 
   ENDTEXT     

   DEFINE WINDOW oWnd TITLE "Usando DIAN desde un webview" SIZE 1050, 700
   oWnd:Hide()
    
   oWebView = TWebView2():New( oWnd )
   oWebView:bOnNavigationCompleted = { | cUrl, hWebView | If( "sessionid" $ cUrl, oWebView:Eval( cResult ),) }

   oWebView:Navigate( "https://muisca.dian.gov.co/WebRutMuisca/DefConsultaEstadoRUT.faces" )
   oWebView:InjectJavascript( JavaScript() )
   // oWebView:OpenDevToolsWindow()
   oWebView:bOnEval = { | cJson, hWebView | If( cJson != "null" .and. cJson != "{}", ( MsgInfo( cJson ), oWnd:End() ),) }
   oWebView:Eval( "consultaDIAN( '79760202' )" )

   ACTIVATE WINDOW oWnd CENTER ;
      ON INIT oWnd:Hide() ;
      ON RESIZE oWebView:SetSize( nWidth, nHeight )

   oWebView:End()

return nil

function Javascript()

   local cCode 

   TEXT INTO cCode 
      function consultaDIAN( numeroIdentificacion ) 
      {
         var inputNIT = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit');
         if (inputNIT) {
            inputNIT.value = numeroIdentificacion;
         } else {
            console.error('No se encontró el campo de entrada para el NIT');
            return;
         }     
         
         var botonBuscar = document.getElementById('vistaConsultaEstadoRUT:formConsultaEstadoRUT:btnBuscar');
         if (botonBuscar) {
            botonBuscar.click();
         } else {
            console.error('No se encontró el botón de búsqueda');
            return;
         }
      }
   ENDTEXT

return cCode

Re: Capturar pagina html y recuperar resultado

Posted: Wed Aug 28, 2024 12:25 pm
by Antonio Linares
el operador $ es pertenencia en cadena, es decir:

"sessionid" $ cUrl // "sessionid" está contenido en cUrl

es equivalente a:

At( "sessionid", cUrl ) != 0

Re: Capturar pagina html y recuperar resultado

Posted: Wed Aug 28, 2024 12:31 pm
by Antonio Linares
los procesos web suelen ser "asíncronos" es por esto que tenemos que usar codeblocks que serán evaluados cuando suceda un determinado evento (en su momento)

bOnNavigationCompleted se evalua cada ve que cambiamos de url. Cuando buscamos a un usuario cambiamos a una url que usa "sessionid" en la url y gracias a esto sabemos que es en ese momento cuando tenemos ya en pantalla la información que buscamos

Asi mismo, bOnEval se evalúa cuando termina la llamada a oWebView:Eval(), nuevamente de forma asíncrona

bOnBind se evalua cuando se llama a SendToFWH() desde javascript // no usado en este ejemplo

la secuencia que usamos basicamente es:

1. navegamos a una url
2. inyectamos código javascript
3. llamamos al código inyectado
4. se cambia de url, detectamos el cambio y evaluamos una expresion javascript que nos da la información que buscamos

todo esto teniendo en cuenta que son procesos asíncronos, luego esperamos a ciertos eventos que ejecutaran nuestros codeblocks

Re: Capturar pagina html y recuperar resultado

Posted: Fri Aug 30, 2024 7:57 pm
by leandro
Excelente Antonio gracias por responder...

Perdoname no habia visto el POST, estaba escondido para mis ojos jejejejejeje

Ven por otro lado no se si no puedes ayudar para que se pueda ocultar el webview y que los usuarios no ven la forma en la que hacemos la consulta, solo que se actualizan las variables en la interfase de usuario :oops:

Gracias de antemano

Re: Capturar pagina html y recuperar resultado

Posted: Sat Aug 31, 2024 6:11 am
by Antonio Linares
En este ejemplo: https://forums.fivetechsupport.com/view ... 60#p272760

se oculta todo y solo se ve el resultado

Re: Capturar pagina html y recuperar resultado

Posted: Sat Aug 31, 2024 10:28 am
by leandro
Excelente Antonio, funciona de maravilla.

En serio que no note que me habías contestado :oops: perdon

De todas formas como siempre muchas gracias.