In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Guardar datos de un documento HTML

Foro público de Xailer en español
Responder
ryder1912
Mensajes: 29
Registrado: Jue Jul 09, 2015 8:17 pm

Guardar datos de un documento HTML

Mensaje por ryder1912 »

Buenas a todos. Consulta, como hago para guardar datos de un documento Html.
Los datos se leen mediante una consulta a la pagina del banco nación (argentina) para obtener la cotización del dólar y como respuesta me devuelve un Html.
El Html de respuesta es un poco largo asi que solo voy a postear la ultima parte. La idea es obtener los datos que vienen a partir del <td> y ponerlos en un array

Código: Seleccionar todo

<div id="cotizacionesCercanas">
    <p class="tituloCotizador">La cotizaciones más cercanas a la fecha solicitada son:</p>
<br clear="all" />
        <div id="tablaDolar" style="text-align:left;">
           <h4 class="cotizador" >Dolar U.S.A</h4>
            <table class="table table-bordered cotizador" >
                    <thead>
                    <tr>
                        <th>Monedas</th>
                        <th>Compra</th>
                        <th>Venta</th>
                        <th>Fecha</th>
                    </tr>
                    </thead>
                    <tbody>
                                        <tr>
                                            <td>Dolar U.S.A</td>
                                            <td class="dest">200.1600</td>
                                            <td class="dest">200.3600</td>
                                            <td>9/3/2023</td>
                                        </tr>
                                        <tr>
                                            <td>Dolar U.S.A</td>
                                            <td class="dest">200.5300</td>
                                            <td class="dest">200.7300</td>
                                            <td>10/3/2023</td>
                                        </tr>

                    </tbody>
            </table>
        </div>

</div>
Este es el código con el que obtengo el Html. Es una función

Código: Seleccionar todo

Function GetCotizacionDolarDivisaBNA()
local aDatCot:={}, oWinHTTP, cURL, cRespuesta
local oDocHtml, oNode
  
      * Creo y Valido el Objeto oWinHTTP
      oWinHTTP := CreateObject( 'MSXML2.XMLHTTP' )
      If Empty(oWinHTTP)
         MsgAlert( 'NO se Pudo Crear el Objeto oWinHTTP', 'Error de Programa')
         Return Nil
      End

      cURL:="https://www.bna.com.ar/Cotizador/HistoricoPrincipales?id=monedas&fecha=27/01/2023&filtroEuro=0&filtroDolar=1"
     * Llamo al Webservice y Defino Opciones
      oWinHTTP:Open( 'GET', cURL, .F. )

      oWinHTTP:SetRequestHeader( "Content-Type" , "text/html; charset=utf-8" )

      * Envio el Archivo y Recibo la Respuesta
      oWinHTTP:Send()

      cRespuesta := oWinHTTP:ResponseText
      oDocHtml:=THtmlDocument():New(cRespuesta)
      oNode   :=oDocHtml:body:divs("tablaDolar") 
    
     // Aqui no se como seguir, la idea es poner los datos de la cotizacion en la variable aDatCot
    
      oWinHTTP:= NIL
      Release oWSFE

Return aDatCot
Saludos.
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5706
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Re: Guardar datos de un documento HTML

Mensaje por jfgimenez »

Hola,

no necesitas usar OLE para descargar una página web. En su lugar puedes usar la clase TAsyncDownload, que además se ejecuta en un segundo hilo y no interrumpe tu programa. Adjunto un ejemplo
Test.zip
(2.51 KiB) Descargado 63 veces
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
Avatar de Usuario
bingen
Mensajes: 565
Registrado: Lun Jul 07, 2014 8:17 pm
Ubicación: Bilbao
Contactar:

Re: Guardar datos de un documento HTML

Mensaje por bingen »

Hay una manera más sencilla, si te registras gratuitamente en:

https://free.currconv.com

y te dan una clave de api xxxxxxxxx podrás utilizar este código, con alguna adaptación por supuesto.

PROBLEMA La API key es solo para 1 mes y luego te la renuevan pero tendrás que cambiarla al mes y si no pagar para que te dejen en paz.
Gestión de administradores de fincas V.15.4 - xFincas.jpg
Gestión de administradores de fincas V.15.4 - xFincas.jpg (23.18 KiB) Visto 503 veces

Código: Seleccionar todo

//------------------------------------------------------------------------------
//Este es el Widget de conversión de moneda que se refresca cada hora
Method WidgetCotizacion( oSender ) CLASS TFrmMain

   WITH OBJECT ::oBevelCotizacion := TBevel():New( ::oBevelBotones )
      :nAlign := alLEFT
      :nAlignMarginLeft    := 10
      :nAlignMarginTop     := 3
      :nAlignMarginBottom  := 3
      :nWidth              := 80
      :lTransparent        := .T.
      :Create()
   END

   WITH OBJECT ::oCotizacionTitle := TLabelEx():New( ::oBevelCotizacion )
      :lAutoSize        :=.T.
      :nAlign           := alTOP
      :nHeight          := 14
      :nTooltipIcon     := tiINFO
      :lTransparent     := .T.
      :Create()
      :OnLButtonUp      := {|| WidgetCotizacionSwitch() }
      :OnRButtonDown    := {|| WidgetCotizacionSelect() }
   END

   WITH OBJECT ::oCotizacionResult := TLabelEx():New( ::oBevelCotizacion )
      :lAutoSize        :=.T.
      :nAlign           := alTOP
      :nHeight          := 14
      :nTooltipIcon     := tiINFO
      :lTransparent     := .T.
      :Create()
      :OnLButtonUp      := {|| WidgetCotizacionSwitch() }
      :OnRButtonDown    := {|| WidgetCotizacionSelect() }
   END

Return Nil

//------------------------------------------------------------------------------

Function WidgetCotizacionRefresh()
   Local cDivisas:="", cOrigen:="", cDestino:="", cCambio  := ""
   Local hData := {=>}, oErr
   Local cResult:= "", cLectura

   //Tomar las divisas desde el INI
   WITH OBJECT TIni():Create( Appdata:cAppPath+"UserData\"+AppData:cUserName+".Ini" )
      cDivisas:=:GetEntry( "WidgetCotizacion", "Divisas", "USD_EUR" )
      :SetEntry("WidgetCotizacion", "Divisas", cDivisas )
      cOrigen  := :GetEntry( "WidgetCotizacion", "Origen", "US Dollar $" )
      cDestino := :GetEntry( "WidgetCotizacion", "Destino", "Euro €" )
   END WITH

   WITH OBJECT TInternet():New()
      IF :Open()
         ProcessMessages()
         hData := :OpenURL( "https://free.currconv.com/api/v7/convert?q="+cDivisas+"&compact=ultra&apiKey=xxxxxxxxxxxx" ) //Donde xxxxxxxxxxx será tu clave de API
         IF !Empty( hData )
            while :ReadFile( hData, @cLectura, 1024 )
                  cResult+= cLectura
                  ProcessMessages()
            end
            :CloseURL( hData )
         ENDIF
         :Close()
      ENDIF
   END


   If cResult<>"{}"
      hb_jsondecode( cResult, @hData )
   Else
      hData:={"Error"=>0}
   Endif

   cCambio  := Left(ToString(hb_HPairAt(hData,1)[2]),8)

   With Object Application:oMainForm:oCotizacionTitle
      :cText          := "<b><#2E2EFE> "+StrTran(hb_HPairAt(hData,1)[1],"_"," => ")
      :cTooltipTiTle := "Conversión de moneda "+cDivisas
      :cBalloon      := "1 "+cOrigen+" => " +cCambio + " "+ cDestino+CRLF+CRLF+"Haga click izquierdo para invertir el cambio y"+CRLF+"click derecho para seleccionar otras monedas"
   End

   With Object Application:oMainForm:oCotizacionResult
      :cText          := "<#886A08><h2>"+cCambio
      :cTooltipTiTle := "Conversión de moneda "+cDivisas
      :cBalloon      := "1 "+cOrigen+" => " +cCambio + " "+ cDestino+CRLF+CRLF+"Haga click izquierdo para invertir el cambio y"+CRLF+"click derecho para seleccionar otras monedas"
   End

return Nil

//------------------------------------------------------------------------------

Function WidgetCotizacionSelect()

   LOCAL hData
   LOCAL cData, cJson:="", aCurrency:={}, aData:={}, aOrigen:={}, aDestino:={}
   LOCAL nLen
   local cUrl  := "https://free.currconv.com/api/v7/currencies?apiKey=a99bcc4dacf1ccbc94fe"

   WITH OBJECT TInternet():New()
      IF :Open()
         IF !Empty( hData := :OpenURL( cUrl ) )
            WHILE :ReadFile( hData, @cData, 65536 )
               cJson += cData
            ENDDO
            :CloseURL( hData )
         ENDIF
         :Close()
      ENDIF
   END

   cJson := SubStr(cJson,12,Len(cJson)-1)
   nLen  := hb_jsondecode( cJson, @hData )

   aCurrency:=HB_HKeys(hData)

*   hb_HGetDef(hData, "currencySymbol", "")
   For nLen:=1 to Len(aCurrency)
      Try
         AAdd(aData, aCurrency[nLen]+" "+hData[ aCurrency[nLen], "currencyName"]+" "+hData[ aCurrency[nLen], "currencySymbol"] )
      Catch
         AAdd(aData, aCurrency[nLen]+" "+hData[ aCurrency[nLen], "currencyName"] )
      End
   Next

   aData :=ASort(aData)
   aOrigen  := aData
   aDestino := aData

   If !MsgEdit("Elija desde que moneda desea hacer la conversión","Conversor de divisas",@aOrigen,"Dinero")
      Return Nil
   Endif
   aDestino:=HB_ADel(aDestino,AScan(aDestino,{|x| x=aOrigen[2]}),.T.)
   If !MsgEdit("Elija a que moneda desea hacer la conversión","Conversor de divisas",@aDestino,"Dinero")
      Return Nil
   Endif

   //Grabar las divisas desde el INI
   WITH OBJECT TIni():Create( Appdata:cAppPath+"UserData\"+AppData:cUserName+".Ini" )
      :SetEntry("WidgetCotizacion", "Divisas", Left(aOrigen[2],3)+"_"+Left(aDestino[2],3) )
      :SetEntry("WidgetCotizacion", "Origen", aOrigen[2] )
      :SetEntry("WidgetCotizacion", "Destino", aDestino[2] )
   END WITH
   WidgetCotizacionRefresh()

Return Nil

//------------------------------------------------------------------------------

Function WidgetCotizacionSwitch()
   Local cDivisas:="", cOrigen:="", cDestino:=""

   //Tomar las divisas desde el INI y cambiarlos de orden
   WITH OBJECT TIni():Create( Appdata:cAppPath+"UserData\"+AppData:cUserName+".Ini" )
      cDivisas:=:GetEntry( "WidgetCotizacion", "Divisas", "USD_EUR" )
      :SetEntry("WidgetCotizacion", "Divisas", Right(cDivisas,3)+"_"+Left(cDivisas,3) )
      cOrigen  := :GetEntry( "WidgetCotizacion", "Origen", "" )
      cDestino := :GetEntry( "WidgetCotizacion", "Destino", "" )
      :SetEntry("WidgetCotizacion", "Origen", cDestino )
      :SetEntry("WidgetCotizacion", "Destino", cOrigen )
   END WITH
   WidgetCotizacionRefresh()
Return Nil

//------------------------------------------------------------------------------
BiSoft Desarrollo de software profesional
http://www.bisoft.es
Avatar de Usuario
xhermita
Mensajes: 177
Registrado: Vie Feb 18, 2011 10:05 pm
Ubicación: Las Palmas de Gran Canaria
Contactar:

Re: Guardar datos de un documento HTML

Mensaje por xhermita »

No he conseguido información sobre la clase THtmlDocument, por las pruebas que hice con tu código parece que no funciona del todo bien. Así que lo he preparado con un poco de código.
Se que el uso que hago del TAsyncDownload no es muy ortodoxo, pero funciona. :D

Código: Seleccionar todo

Function GetCotizacionDolarDivisaBNA()
   LOCAL hDatCot := { "Moneda" => "", "Compra" => 0, "Venta" => 0, "Fecha" => ""}
   LOCAL cRespuesta, lOk := .F.
   LOCAL cHoy := StrZero( Day( Date() ), 2 ) + "/" + StrZero( Month( Date() ), 2 ) + "/" + StrZero( Year( Date() ), 4 )
   LOCAL nIni, nFin

   // Llamo al Webservice
   WITH OBJECT TAsyncDownload():New()
      :cURL := "https://www.bna.com.ar/Cotizador/HistoricoPrincipales?id=monedas&fecha=" + cHoy + "&filtroEuro=0&filtroDolar=1"
      :OnDisconnect := {|oSender| cRespuesta := :cBuffer, lOk := .T. }
      :Create()
      :Run()

      DO WHILE !lOk
         ProcessMessages(100)
      ENDDO

      IF :nStatus <> 200
         MsgInfo( "Error: [" + ToString( :nStatus ) + "] " + :cError )
      ENDIF

   END WITH

   IF !Empty( cRespuesta )
      nIni := HB_At( "<td>Dolar U.S.A</td>", cRespuesta )
      if nIni > 0
         // Encontrada Moneda
         hDatCot["Moneda"] := "Dolar U.S.A."
         nIni := HB_At( '<td class="dest">', cRespuesta, nIni )
         IF nIni > 0
            // Encontrada Compra
            nIni += 17
            nFin := HB_At( '</td>', cRespuesta, nIni ) - nIni
            hDatCot["Compra"] := Val( SubStr( cRespuesta, nIni, nFin ) )
            nIni := HB_At( '<td class="dest">', cRespuesta, nIni )
            IF nIni > 0
               // Encontrada Venta
               nIni += 17
               nFin := HB_At( '</td>', cRespuesta, nIni ) - nIni
               hDatCot["Venta"] := Val( SubStr( cRespuesta, nIni, nFin ) )
               nIni := HB_At( '<td>', cRespuesta, nIni )
               IF nIni > 0
                  // Encontrada Fecha
                  nIni += 4
                  nFin := HB_At( '</td>', cRespuesta, nIni ) - nIni
                  hDatCot["Fecha"] := CToD( SubStr( cRespuesta, nIni, nFin ) )
               ENDIF
            ENDIF
         ENDIF
      ENDIF
   ENDIF

RETURN hDatCot
Te devuelve un Hash con los cuatro valores (Moneda,Compra,Venta y Fecha)
Pedro Amaro
2PC Service

Xailer / Néfele / MySQL-MariaDB / SQLServer
Responder