Saltar al contenido

Obtener datos de página web con sistema de logueo.


Recommended Posts

Buenas,

Este es mi primer post, no estoy muy puesto en el mundo de excel por lo que pido disculpas si resulto muy torpe.

Tengo una excel (Office 2003) que toma datos de una página web cada 60 minutos, dicha web, tiene un sistema de logueo. Esto no me supone mucho problema, ya que con vba, mas o menos, logro conectarme y obtener los datos que me interesan. El problema aparece al pasar un tiempo, que la sesión caduca y deja de actualizar.

He observado que el id de sesión se pasa en la URL y cuando esta caduca (cada 24 horas) el id ya no vale. Al reconectar, el id ha cambiado, por lo que me es imposible referenciar mi excel a la dirección que quiero ya que esta cambia cada 24 horas.

La URL sería como esta:

http://www.miweb.com/aplicacion/datosdelobjeto.do?objt=E101&opcion=Ene&id=-8339212974592973078

Donde el trozo final (id=-8339212974592973078) cambia cuando caducar la sesión.

¿Cómo puedo evitar que se me caduque la sesión o tomar el nuevo id de sesión para incluirlo en el URL?

Agradecería muchísimo algo de ayuda.

Un saludo.

Enlace a comentario
Compartir con otras webs

Yo también tengo un macro que se conecta a una web para recoger datos

Me las vi y me las desee para logearme y bajarme los datos

Si cambia la dirección no creo que sea nada facil saber porqué...

Yo tuve suerte, porque la página donde me logeo utiliza peticiones a traves de javascripts, y examinando los archivos que se baja el navegador al logearse (archivos .js) pude ir deduciendo como hacerlo en excel

en tu caso, a saber si la página va por php u otro lenguaje... si es en javascritp, que lo más seguro es que no, te podría echar un cable

Enlace a comentario
Compartir con otras webs

Otra cosa que se me ocurre, es que uses las librerías XMLHttp, te logees con el comando "open", crees un objeto "domdocument" y grabes la respuesta inmediata del servidor en ese objeto "domdocument" con la propiedad "responsetext"

en esa respuesta igual está la terminación que cambia cada día... si es así, lo tienes fácil, simplemente tendrías que copiar esa terminación y ponerla en otra url, para luego hacer otro "open" y acceder a la url final

si te interesan más detalles sobre esto, chifla y te puedo ir dando indicaciones con el código

Enlace a comentario
Compartir con otras webs

Buenas,

Muchas gracias por tus respuestas.

Decirte que la aplicación web está escrita en java con JSP, XML,... Tengo también los ficheros .class, vamos que tengo acceso a todo lo que necesite de la aplicación web pero no puedo modificarla.

Voy a intentar informarme de lo que comentas de las librerías XMLHttp ya que no lo he utilizado nunca.

Espero encontrar la luz al final del tunel...

Enlace a comentario
Compartir con otras webs

Adjunto unas pincelas de lo hablo para que vayas enlazando con lo que encuentres por ahí.

Para este macro debes activar "Herramientas/Referencias.../Microsoft XML, v5.0

Sub AbreWeb()

Dim XML As New MSXML2.XMLHTTP
Dim XMLDoc As New MSXML2.DOMDocument
Dim url As String
Dim st As String

' LOGIN:
' Usaremos directamente a la página de verificación:
url = "https://www.mipaginabancaria.com"
' Crear objeto xmlhttp:
Set XML = CreateObject("MSXML2.XMLHTTP")
' Envío de solicitud a servidor:
With XML
.Open "POST", url, False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
' Aquí introducimos el usuario y contraseña. Las palabras "Name" y "Password" deben aparecer como
' "name" dentro del código web del formulario de entrada.
.send "Name=noblejis&Password=123456"
End With

' CREACIÓN DE OBJETO "XMLDOC":
Set XMLDoc = CreateObject("MSXML2.DOMDocument")
' Propiedades de dicho objeto:
XMLDoc.async = False
XMLDoc.validateOnParse = True
' Cargar Respuesta:
st = XMLDoc.loadXML (XML.responseText)
' Otra forma de cargar la respuesta sería (en caso de que no funcionara la orden anterior):
' st = XMLDoc.load (XML.responseText)
End Sub[/CODE]

lo que no recuerdo bien es como visualizar la variable "st", creo recordar que ejecutando paso por paso con F8, y mirando la ventana de Locales podías ver el contenido... pero creo que si "st" era demasiado grande no era fácil...

Una vez tengas el "response", buscas si está la terminación que aparece en la 2º url, si es así chifla y te sigo pasando código

Login.zip

Enlace a comentario
Compartir con otras webs

Buenas,

De nuevo, mil gracias por tu implicación.

He probado el código que me adjuntas. La variable st, al ejecutar el código, pasa a tener valor "falso", por lo que creo que no me vale, pero he encontrado algo interesante. La página a la que redirecciona después del login tiene un campo input de tipo hidden llamado "marca", que contiene el valor del id!!!, vamos, que guardan el id en ese campo para usarlo luego.

Sabiendo esto, creo que la mejor forma de hacerlo sería con una macro que haga login en la aplicación y después guarde en una variable el id que se encuentra en "marca".

Voy a probar a ver que sale...

Enlace a comentario
Compartir con otras webs

Hola:

mmmmmm me acabo de dar cuenta que me he equivocado. La variable "st" te da "false" porque "loadXML" da un "boolean"

Veamos... para extraer la "id" por XMLHttp necesitas conseguir que Excel obtenga el "response", y que compruebes que dentro de ese "response" está esa "id".

Prueba este código "paso a paso" con F8, con la ventana de Locales abierta.

Sub AbreWeb()

Dim XML As New MSXML2.XMLHTTP
Dim url As String
Dim st As String

' LOGIN:
' Usaremos directamente a la página de verificación:
url = "https://www.mipaginabancaria.com"
' Crear objeto xmlhttp:
Set XML = CreateObject("MSXML2.XMLHTTP")
' Envío de solicitud a servidor:
With XML
.Open "POST", url, False
.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
' Aquí introducimos el usuario y contraseña. Las palabras "Name" y "Password" deben aparecer como
' "name" dentro del código web del formulario de entrada.
.send "Name=noblejis&Password=123456"
End With

' Cargar Respuesta:
[B]st = XML.responseText[/B]
End Sub[/CODE]

ahora, la variable "st" debiera estar "llena"... fíjate en la ventana de locales como evoluciona la variable "XML" mientras avanzas en el código. Dentro de "XML", verás el "response" en la casilla "responseText".

Si no sale o hay algún tipo de error, es que el método de login que te he pasado no es compatible con la página

Ojo, es importante saber poner correctamente los argumentos de la orden "send"

Ya me cuentas

Enlace a comentario
Compartir con otras webs

Sobre la orden "send" comentar lo siguiente:

Las palabras "Name" y "Password" deben ser los valores de las etiquetas "name" del formulario de entrada del usuario y la contraseña respectivamente.

La "url" debe ser donde se envía el nombre de usuario y contraseña.

Un saludo y suerte

Enlace a comentario
Compartir con otras webs

Ha funcionado!!!

En st se ha cargado el código de la página.

He utilizado la función Mid(cadena,n,m) para obtener el id que se encuentra dentro de st y lo he metido en una nueva variable que he llamado id (que original soy...) y la he añadido al final de la URL de la que quiero capturar los datos.

Todo esto ha funcionado a la perfección!

Lo que no se, es si se va a ejecutar automáticamente cada 60 minutos.

Al utilizar el QueryTables para capturar los datos de la web, he puesto la propiedad .RefreshPeriod = 60, pero no actualiza y en el caso de que lo llegase a hacer, no se ejecutaría el código que obtiene el nuevo id.

Voy a hacer unas pruebas y te comento.

Gracias por la ayuda.

Enlace a comentario
Compartir con otras webs

Me alegro que vaya poco a poco.

Te puedes ahorrar la variable "st" y usar en su lugar "responseText"

En su momento deseché ese método de QueryTables, pues el servidor donde me bajo los datos no es una base de datos (creo), sino una página con formato XML donde todos los datos cambian cada pocos segundos... me interesaría saber tu opinión sobre si hacer un QueryTables me vendría mejor...

Por otro lado, el servidor creo que no te actualiza la informción porque igual tienes que enviar unos "requestheaders" al servidor. Intenta abrir la 2º url con el siguiente código:

XML.Open "GET", url, False, Null, Null

XML.setRequestHeader "Expires", "0"
XML.setRequestHeader "Pragma", "no-cache"
XML.setRequestHeader "Pragma", "no-store"
XML.setRequestHeader "cache-control", "no-cache, must-revalidate"
' Envíar solicitud:
XML.send[/CODE]

Estos "requestheaders" son del servidor donde me conecto, debes de usar los "requestheaders" del servidor donde te conectas tú. Búscalos dentro de los archivos que tienes de la web, sobretodo de los archivos que se descargan una vez te logeas con el navegador web.

Luego para actualizar los datos cada "x" tiempo, uso el método "Application.Ontime", hay mucha info por ahí sobre ello

Enlace a comentario
Compartir con otras webs

Comentarte que los datos que capturo, también cambian cada cierto tiempo. He tenido toda la tarde la macro activa y me ejecuta la consulta cada 60 minutos, no se que hará cuando el id cambie, ya que este caduca cada día.

Desconozco las ventajas o inconvenientes que tiene hacerlo con QueryTables, sólo se que es el que genera automáticamente excel si grabas una macro de captura de datos desde página web y por eso, todos mis intentos fueron con este método.

Ahora mismo no tengo el código delante, mañana te lo adjunto.

Saludos.

Enlace a comentario
Compartir con otras webs

Hola

Puedes usar QueryTables, primero te autentificas en la página y luego redireccionas a la url donde esta la información y listo usa el metodo PostText para pasarle las variables (en el foro hay varios ejemplos).

Las ventajas que he encontrado al usar QueryTables, es que al ser nativas del propio excel, se gana bastante velocidad (no necesitas bucles para convertir tablas por ejemplo).

Si usas un objeto externo de excel, te recomiendo tratar todos los datos desde vba (usa matrices si es necesario), y al final rellenas las celdas directamente de la matriz, con ello ganaras velocidad, una ventaja es que puedes establecer encabezados en el mensaje.

saludos

Enlace a comentario
Compartir con otras webs

Gracias a los dos.

Investigaré si con QueryTables puedo aumentar la velocidad de mi código.

Un saludo.

Edito: Ahhhh QueryTables = hacer un web query... esa fue mi primera opción antes de usar XMLHttp, pero no se ajusta a mis necesidades (o al menos yo no pude ajustarla).

Para no ensuciar este post, abro otro aquí:

https://www.ayudaexcel.com/foro/macros-programacion-vba-10/pendiente-extraccion-datos-via-querytables-21053/#post105708

Enlace a comentario
Compartir con otras webs

  • 4 weeks later...

Archivado

Este tema está ahora archivado y está cerrado a más respuestas.

  • 97 ¿Te parecen útiles los tips de las funciones? (ver tema completo)

    1. 1. ¿Te parecen útiles los tips de las funciones?


      • No
      • Ni me he fijado en ellos

  • Ayúdanos a mejorar la comunidad

    • Donaciones recibidas este mes: 0.00 EUR
      Objetivo: 130.00 EUR
  • Archivos

  • Estadísticas de descargas

    • Archivos
      177
    • Comentarios
      90
    • Revisiones
      27

  • Crear macros Excel

  • Mensajes

    • Hola que tal amigos programadores por favor me podrían ayudar con una macro que me genere un archivo CSV delimitado por comas, la estructura del archivo CSV no deberá llevar encabezado, los datos del archivo CSV serán obtenidos de la hoja “Datos”. En la columna A: deberá tener la clave clues que se toma de la columna B de la hoja Datos En la Columna B: el Código (son 230 codigos que van del rango G1:IB1 de la hoja datos) En la Columna C: el valor almacenado a su correspondiente al código y clues En la Columna D: el número del mes que se obtendrá de la de la columna E de la hoja Datos En la Columna E: el año que se tomará de la columna F de la hoja de Datos   Son 230 códigos por lo que la macro generará 230 filas por cada clave clues que tenga la hoja Datos En el archivo anexo una hoja llamada CSV para que vean la estructura que tendrá, el archivo CSV estará delimitado por comas   Les agradecería mucho que me ayuden por favor, Dios los bendiga Exportar datos a csv.xlsx
    • Hola buenas tardes.   Debido al trabajo debo estar comparando en un periodo unos archivos dentro de una carpeta o subcarpeta. en base a la fecha de creacion o modificacion.  pero tengo que estar viendo carpeta por carpeta y aveces son varios. Con una macro intente  listar los archivos de cualquier carpeta y subcarpeta, esto activandolo segun la celdaactiva. El problema es que tiene algunos errores. 1. si la carpeta cuenta con subcarpetas me los manda a muchas filas abajo. Mi idea es hoja(Así debe quedar) Que con una macro pueda seleccionar la carpeta desde el buscador y me de la lista de archivos a partir de la fila 6. siendo columna A= fecha de modificación, columna B =Fecha de creación y columna C=Nombre del archivo con hiperlink. Con otro o con la misma macro poder seleccionar otra carpeta y sus subcarpetas, según sea el caso. y me liste a partir de la columna F de la fila 6 Siendo La columna F=Nombre del archivo, columna H=fecha de creación, columna I=ultima modificación   Para así poder acceder y comparar mis archivos, directamente desde excel.   Muchas gracias Mariano       Listar archivos de 2 carpetas para comparar.xlsm
    • Hola buenas, Os presento mis dudas. Tengo un libro  (llamémosle LibroDestino) con dos módulos, uno de definición de variables "ModDef" y otro de inicializacion de esas mismas variables "ModCfg". Necesito que al copiarme una hoja de otro libro(llamémosle LibroOrigen), mediante un procedimiento, sobrescribir el modulo de inicialización de variables del LibroDestino con el  contenido del módulo que hay en el LibroOrigen. Destacar que los dos módulos de cada libro tienen el mismo nombre "ModCfg". Y tienen una única variable llamada "Mensaje". En el LibroDestino tiene el valor "Hola" y en el LibroOrigen el valor "Adiós" Este procedimiento lo realiza perfectamente,  es decir se sobrescribe, pero si en el mismo procedimiento quiero utilizar el nuevo valor de esa variable, me conserva el valor de la variable anterior. Para hacer las comprobaciones he ejecutado un MsgBox al empezar y al acabar el procedimiento, pero en los dos casos me devuelve el valor original del LibroDestino el valor "Hola", cuando mi idea es que al sobrescribir el modulo con el nuevo valor de la variable, el último MsgBox me devuelva el valor "Adios". Mi objetivo es poder tener la inicialización de esas variables en un libro que no sea el de trabajo (LibroDestino), ya que según la hoja que importe puedo requerir que las variables tengan un valor u otro. ¿Por que no me coge en el procedimiento el nuevo valor de la variable? ¿Cómo podría conseguirlo? He tenido que activar en VBA  la referencia Microsoft visual basic for applications extensibility 5.3 desde  Herramientas -> Referencias. Creo que es la única manera de poder trabajar con los módulos desde VBA, aunque si se pudiera de otra manera creo que sería mas óptimo. Mil gracias de antemano, un saludo!         Libro1_Prueba.xlsm Libro2_Prueba.xlsm
    • Agradecido Antoni! Tus sugerencias me ayudaron mucho! Como pudiese hacerte llegar el archivo?
    • Prueba este código. Sin el archivo no te puedo ajustar más. Private Sub btnCargaBancos_Click() 'El tipo de dato debe especificase para cada variable Dim TasaCompra As Double, TasaVenta As Double, InvBanesco As Double, InvVzla As Double Dim MontoBanesco As Double, MontoVzla As Double, TasaDiaBan As Double, TasaDiaVzla As Double Dim TasaActual As Double 'Hay que comprobar que los textbox tienen contenido numérico 'Los datos numéricos solo pueden contener números y el separador decimal, cualquier otro caracter dará error al convertir If Not IsNumeric(txtInverBanesco) Or _ Not IsNumeric(txtInverVzla) Or _ Not IsNumeric(txtTasaCompra) Or _ Not IsNumeric(txtTasaVenta) Then MsgBox "Los datos deben ser numéricos", vbCritical Exit Sub End If InvBanesco = CDbl(txtInverBanesco) InvVzla = CDbl(txtInverVzla) TasaCompra = CDbl(txtTasaCompra) TasaVenta = CDbl(txtTasaVenta) 'Los datos de los divisores no pueden ser 0 (Indeterminación matemática) If TasaCompra = 0 Or _ InvBanesco = 0 Or _ InvVzla = 0 Then MsgBox "Los datos no admiten valor cero", vbCritical Exit Sub End If MontoBanesco = (InvBanesco / TasaCompra) * (1 - 0.18 / 100) * (TasaVenta * (1 - 0.18 / 100)) MontoVzla = (InvVzla / TasaCompra) * (1 - 0.18 / 100) * (TasaVenta * (1 - 0.18 / 100)) TasaDiaBan = (MontoBanesco / InvBanesco) * (1 - 0.055) TasaDiaVzla = (MontoVzla / InvVzla) * (1 - 0.055) If TasaDiaBan < TasaDiaVzla Then TasaActual = TasaDiaBan Else TasaActual = TasaDiaVzla End If 'En VBA, los datos numéricos no admiten ser formateados, formatear directamente en las celdas, 'MontoBanesco = FormatNumber(MontoBanesco, 2, True, vbFalse) 'MontoVzla = FormatNumber(MontoVzla, 2, True, vbFalse) 'TasaActual = FormatNumber(TasaActual, 5, True, False) txtBcoBanesco = MontoBanesco txtBcoVenezuela = MontoVzla txtTasaDiaria = TasaActual End Sub  
  • Visualizado recientemente

    • No hay usuarios registrado para ver esta página.
×
×
  • Crear nuevo...

Información importante

Echa un vistazo a nuestra política de cookies para ayudarte a tener una mejor experiencia de navegación. Puedes ajustar aquí la configuración. Pulsa el botón Aceptar, si estás de acuerdo.