Banner clix

jueves, 19 de febrero de 2015

Macro: consultar páginas o formularios web para obtener datos

Este macro puede resultar de gran utilidad a la hora de consultar gran cantidad de páginas buscando la misma información (por ejemplo, rastreos de envíos, consultas de información personal, entre otras, siempre y cuando no pidan un captcha o mayor verificación), en este caso vamos a hacer una prueba con Instagram, pongamos de ejemplo que necesitamos consultar 30 cuentas de instagram en busca de la información básica, en éste caso la cantidad de publicaciones (posts), los seguidores (followers) y la cantidad de seguidos (following), ademas supongamos que no tenemos acceso al API de instagram ni sabemos como utilizarlo para fines prácticos del ejemplo. El libro debería quedar de la siguiente manera:




La idea del libro es colocar en la primera columna, todas las cuentas que deseamos revisar (desde una hasta miles), luego, ejecutando un macro se obtenga el resto de la información necesaria sin tener que consultar una por una. (Para ver como activar, utilizar y autorizar Macros en tu ordenador ve el siguiente post: Tip: Macros, que son y como activar y ejecutar Macros en excel.)

Ahora bien, necesitamos el código que nos ayudará a obtener toda la información, primero se repasará de manera general que necesitamos y al final puedes conseguir el código completo con sus comentarios.

Lo primero que vamos a obtener es la cantidad de celdas usadas en A para no realizar busquedas sobre campos vacios, para lograr esto, utilizamos el siguiente codigo:

FilaUlt = Columns("A:A").Range("A65536").End(xlUp).Row

Ya que sabemos cuantas celdas se utilizaron en A, vamos a realizar un bucle para obtener la información una a una de las cuentas indicadas a partir de A2, en el bucle cargamos la información de la celda analizada a una variable que completará la dirección a la que vamos a consultar, por ejemplo si en la celda A2 se encuentra la palabra yomaquillo (es la cuenta con la que haremos pruebas) el macro completará la dirección http://instagram.com/yomaquillo y obtiene el código fuente de esa dirección, donde se encuentra la información que necesitamos (NOTA: probablemente no sea el mismo código fuente que se puede ver haciendo clic derecho y luego ver código, pues este contiene toda la información en java y no el código final que ve Excel, esto puede ocurrir con algunas páginas en casos excepcionales por lo que al final se incluye un tip para por ver que es lo que llega finalmente a Excel si tienes problemas con el código fuente).

La parte complicada es ubicar la información que necesitamos en el código fuente, primero debemos ubicar donde se encuentra la información de manera visual, para esto podemos ver el código fuente en un bloc de notas y buscar por ejemplo en número de seguidores, al ubicarlo, podemos probar con etiquetas html cercanas que no se repitan, en el caso de instagram, la información está contenida en una etiqueta div con nombre "user-stats", la palabra user-stats no se repite en toda la pagina por lo que nos servirá como primer identificador y puesto que toda la información esta en una etiqueta div, buscamos el cierre de esa etiqueta como segundo identificador, que ya no importa que se repita en partes anteriores, pues con el primer identificador se restringe la búsqueda. El código siguiente sirve para ilustrar todo el párrafo anterior:

<div class=""user-stats"">
                <ul>
                    <li>
                        <span class=""number-stat"">114</span> posts
                    </li>
                    <li>
                        <span class=""number-stat"" title=""654"">654</span> followers
                    </li>
                    <li>
                        <span class=""number-stat"">583</span> following
                    </li>
                </ul>
            </div>
            <p class=""user-action"">
               <span class=""avatar-action"">
                    <a class=""button edit-profile-button"" href=""/accounts/login/?next=/yomaquillo/"">Follow</a>
                </span>
            </p>
        </div>
Ahora que tenemos solo la parte que nos interesa, se puede dividir la información con el caracter >  en un arreglo que contenga todos los resultados divididos, luego se limpia cada resultado que nos interesa (para este caso fueron las posiciones del 4, 8 y 12 del arreglo datos) utilizando la función replace para eliminar lo que rodeaba al número y tenemos nuestra información limpia y presentable.

Aquí les dejo el código con los comentarios para que puedan aplicarlo a lo que necesiten, éste código puede utilizarse para consultar formularios con método POST  siempre que se pueda accesar por medio de la barra de direcciones. Un ejemplo puede ser la página de consulta de lugar de votación para las elecciones de Colombia, la página de la registraduría utiliza la siguiente dirección: http://wsr.registraduria.gov.co/servicios/censo.htm?nCedula=1111111111&buscar4=Buscar donde 1111111111 se debe modificar por el número de cedula a consultar para construir el vinculo que siguiendo éste ejemplo debería estar en la columna A, el resultado de la página debería luego analizarse y empezar a buscar etiquetas cercanas a la información que queremos ubicar y utilizar, como dije anteriormente ésto es lo mas complicado de ésto, pero con un poco de tiempo e ingenio se pueden ahorrar miles de horas de trabajo.

Sub Obtener_datos()



Dim FilaActual As Integer

Dim user As String

Dim FilaUlt As Integer

'Obtener ultima fila utilizada de la columna A

FilaUlt = Columns("A:A").Range("A65536").End(xlUp).Row



For FilaActual = 2 To FilaUlt

    'Se carga en user el nombre del usuario desde la celda

    'y se eliminan espacios en blanco por precaucion

    user = LTrim(RTrim(Range("A" & FilaActual)))

    'si hay error, continuar al siguiente bloque If

    On Error Resume Next

    'Ocultar el procedimiento

    Application.ScreenUpdating = False

    'la web a consultar se construye

    link = "http://instagram.com/" & user

    'estas dos variables son las que rodearan el texto que nos interesa

    Principio = "user-stats"

    Final = "</div>"

    'crear un objeto xmlhttp vacio

    Set XML = CreateObject("Microsoft.XMLHTTP")

    'acceder a la página web

    XML.Open "GET", link, False

    XML.send

    'pasar el codigo fuente de la web en html a una variable

    Source = XML.responsetext

    'buscar la posicion del texto que rodea la informacion que necesitamos.

    posicion1 = InStr(Source, Principio)

    Posicion2 = InStr(posicion1, Source, Final)

    'se extrae informacion en medio de las posiciones y se pasa a una variable

    datogen = Mid(Source, posicion1, (Posicion2 - posicion1))

       

        'si no hay errores, proceder

        If Err = 0 Then

            'crear array separando los elementos por el caracter ">"

            datos = Split(datogen, ">")

            'se crean varias cadenas separadas por ">" y se remueve el </span del final

            datos(4) = Replace(datos(4), "</span", "")

            datos(8) = Replace(datos(8), "</span", "")

            datos(12) = Replace(datos(12), "</span", "")

            'imprimir resultados

            Range("B" & FilaActual) = datos(4)

            Range("C" & FilaActual) = datos(8)

            Range("D" & FilaActual) = datos(12)

        Else

            'si hay error, es probable que el usuario no exista

            Range("f" & FilaActual) = "El usuario " & user & " no existe"

        End If

       

    'Imprimir hiperlink para consultar directamente la pagina

    ActiveSheet.Hyperlinks.Add Anchor:=Range("e" & FilaActual), Address:=link, TextToDisplay:=user, ScreenTip:="Consultar Intranet"

    'Se limpia el objeto XML

    Set XML = Nothing



Next FilaActual

Application.ScreenUpdating = True

End Sub

Por último, les dejo un pequeño código con el que pueden analizar el código fuente que está viendo excel a la hora de hacer una consulta con el macro anterior, en caso de tener discrepancias con el código visto desde los navegadores (suele suceder con páginas muy dinámicas como instagram o twitter).

Sub codigofuente()



'modificar aqui la dirección que desean consultar

link = "https://instagram.com/yomaquillo"



Set XML = CreateObject("Microsoft.XMLHTTP")

XML.Open "GET", link, False

XML.send

texto = XML.responsetext



Range("A1") = texto
End Sub

Espero que les sea de gran utilidad, sobre todo con páginas que no tengan APIs para su consulta de datos ni tengan otras verificaciones como CAPTCHAs.

1 comentario:

  1. Cordial saludo, ante nada muchas gracias por su gran aporte... quisiera tener un poco mas de detalle de como debo programar la macro para la pagina de la registraduria. muchas gracias por su valiosa ayuda.

    ResponderEliminar