Ir al contenido

Extract Structured Data

Tipo: page-extract-table  ·  Paquete: Browser v1.0.10  ·  Salida: DataTable

Extrae datos con forma de tabla de la página y los convierte en una DataTable, lista para recorrer, filtrar o volcar a Excel. Funciona con tablas HTML (<table>) y también con datos que se ven como una tabla aunque no lo sean: calendarios, cuadrículas de tarjetas o diseños hechos con CSS grid/flex. Si los datos están paginados, puede recorrer todas las páginas por ti.

Es muchísimo más eficiente que leer celda por celda con Get Text: una sola actividad te trae toda la tabla.

Tiene dos modos, que eliges con mode:

ModoPara quéParámetros que usa
table (por defecto)Una <table> de HTMLselector
smartCualquier cuadrícula visual, sin <table>container, cells, headers, rowHeaders

Si dejas mode vacío pero indicas cells, se usa el modo smart. En los dos modos, la actividad espera primero a que el elemento raíz (la tabla o el contenedor) esté visible, hasta timeout; si el selector coincide con varios, usa el primero.

Localiza el <table> por su selector; si el selector apunta a un contenedor, usa la primera tabla que haya dentro.

  • Encabezados: las celdas <th>/<td> del <thead>. Si la tabla no tiene <thead>, la primera fila se toma como encabezado.
  • Filas: las filas del <tbody> (o, sin <thead>, todas las filas después de la primera). De cada fila se leen solo las celdas <td>; las filas sin ninguna <td> (subtítulos hechos solo con <th>) se descartan.
  • Texto de cada celda: su texto visible (innerText), sin espacios al principio ni al final.

Reconstruye la cuadrícula según la posición en pantalla de cada elemento:

  1. Busca dentro de container (o de toda la página si lo dejas vacío) los elementos de cells, headers y rowHeaders.
  2. Columnas: cada elemento de headers define una columna, ordenadas de izquierda a derecha; su texto es el nombre de la columna. Sin headers, las columnas se deducen agrupando las celdas que están en la misma franja vertical.
  3. Filas: cada elemento de rowHeaders define una fila, ordenadas de arriba abajo, y su texto va en una primera columna adicional. Sin rowHeaders, las filas se deducen agrupando las celdas que están en la misma franja horizontal.
  4. Cada celda va a la columna y la fila cuya franja contiene su centro (o a la más cercana). Si dos celdas caen en la misma posición, sus textos se unen con |; las posiciones sin celda quedan vacías.

El texto de cada elemento se toma con los espacios y saltos de línea reducidos a un solo espacio. Los elementos deben estar dibujados en la página: lo que esté oculto no tiene posición útil.

Si indicas nextPage (el botón “siguiente”), tras leer la primera página repite hasta maxPages páginas en total:

  1. Se detiene si el botón no está visible o está deshabilitado: atributo disabled, aria-disabled="true", o una clase disabled, is-disabled, btn-disabled, page-item-disabled o pagination-disabled en el botón (o disabled / is-disabled en su elemento padre).
  2. Hace clic en el botón y espera a que llegue la página nueva completa. Antes del clic toma una huella de todo el contenido: en el modo table, el texto de todas las filas del cuerpo; en el modo smart, el texto y la posición de cada elemento de cells dentro del contenedor. Después del clic espera, hasta timeout, a que esa huella cambie y se quede quieta un momento (300 ms; 1 s si la página nueva llega vacía), a que la red quede inactiva (hasta 3 s) y a que terminen las peticiones que lanzó el clic (hasta 5 s). Así no lee una página a medio pintar ni un estado de «Cargando…», y no tarda más de lo necesario aunque dos páginas empiecen con la misma fila.
  3. Lee la página y agrega sus filas. Se detiene si una página llega sin filas.

Si tras el clic el contenido no cambia dentro de timeout, la actividad falla en lugar de leer otra vez la misma página: así nunca se agregan filas duplicadas ni se entregan datos incompletos en silencio. Suele indicar que nextPage apunta a un elemento que no carga la página siguiente, o que el sitio, en su última página, deja el botón activo sin deshabilitarlo; en ese caso limita el recorrido con maxPages. Si el contenido cambia pero no deja de cambiar (por ejemplo, un reloj dentro de la tabla), al vencer timeout se lee como esté y se deja un aviso en el registro. Desde la versión 1.0.10.

Los encabezados se toman solo de la primera página.

Ninguno. (En el modo table necesitas selector; en el modo smart, cells.)

ParámetroTipoPor defectoDescripción
pageZoanPageSession—La sesión de página. Omítela dentro de un body; fuera, pasa la variable de la sesión (p. ej. page = page).
modestring"table"Modo de extracción: table (lee una <table>) · smart (reconstruye la cuadrícula por posición). Vacío con cells indicado: smart.
selectorselector—Modo table: el elemento <table> (o un contenedor que lo contenga). Obligatorio en ese modo.
containerselectortoda la páginaModo smart: el contenedor que delimita la extracción (la raíz de la cuadrícula o del calendario).
cellsselector—Modo smart: las celdas con datos. Cada elemento se ubica en la cuadrícula según su posición. Obligatorio en ese modo.
headersselector—Modo smart: los encabezados de columna. Su texto da nombre a las columnas y su posición horizontal define cada columna.
rowHeadersselector—Modo smart: las etiquetas de fila (el eje izquierdo, p. ej. las horas). Agrega una primera columna con la etiqueta y alinea cada fila por su posición vertical.
nextPageselector—Botón de “página siguiente”. Si se indica, extrae todas las páginas hasta que el botón desaparece o se deshabilita. Si un clic no cambia el contenido, la actividad falla (ver Paginación).
maxPagesint100Máximo de páginas a extraer, contando la primera.
timeoutnumber30000Tiempo máximo en ms a esperar la tabla o el contenedor, y a que cambie tras cada página. Vacío, 0 o negativo: el de la configuración del proyecto o, si no hay, 30000.

Devuelve un DataTable en el que todas las columnas son de texto (string):

ModoColumnasFilas
tableUna por celda de encabezado, con su texto. Un encabezado vacío se llama Col1, Col2… según su posición. Si una fila trae más celdas que encabezados, se agregan columnas ColN.Una por fila con datos; las celdas que falten quedan vacías.
smartCon rowHeaders: primero la columna de etiquetas (Col1) y luego una por encabezado. Las columnas sin texto de encabezado (o todas, si no hay headers) se llaman Column 1, Column 2…Una por etiqueta de fila (o por franja deducida).

En casos límite:

  • Una tabla con encabezados pero sin filas devuelve una DataTable con sus columnas y 0 filas.
  • Si el selector no apunta a ninguna tabla, o en modo smart ninguna celda coincide, la actividad falla (ver abajo).

Extraer un listado paginado de movimientos y recorrerlo:

Extract Structured Data selector = (#tablaMovimientos) nextPage = (.btn-siguiente) maxPages = 10 → output: movimientos
Log message = "Filas extraídas: " + rowCount(movimientos)
For Each items = movimientos itemVariable = fila
└─ activities:
Log message = str(fila["Fecha"]) + " — " + str(fila["Valor"])

Leer una agenda semanal de reservas de salas que no usa <table>: los días son las columnas y las horas, las filas:

Extract Structured Data mode = smart container = (.agenda) cells = (.reserva) headers = (.agenda-dia) rowHeaders = (.agenda-hora) → output: agenda
For Each items = agenda itemVariable = fila
└─ activities:
Log message = str(fila["Col1"]) + " lunes: " + str(fila["Lunes"])
MensajeCausa y solución
En el modo 'table' se requiere un selector de tabla.Estás en modo table (o con mode vacío y sin cells) y no indicaste selector. Indícalo, o cambia a mode = smart.
No se encontró ninguna tabla en el selector indicado.El elemento existe pero no es una <table> ni contiene una. Apunta a la tabla, o usa el modo smart si los datos no están en una <table>.
Ningún elemento coincidió con 'cells' dentro del contenedor.En modo smart, el CSS de cells no encontró nada dentro de container. Revisa el selector (debe abarcar todas las celdas) y que el contenedor sea el correcto.
Paginación: después de pulsar el botón de página siguiente en la página N, el contenido no cambió en … ms (se llevaban … filas extraídas). …El clic en nextPage no cambió el contenido dentro de timeout. Revisa que el selector apunte al botón que carga la página siguiente; si el sitio es lento, aumenta timeout; si la última página deja el botón activo, limita con maxPages. Desde la versión 1.0.10.
Timeout 30000ms exceededLa tabla o el contenedor no se hizo visible a tiempo. Revisa el selector o espera antes con Wait For.
A column named '…' already belongs to this DataTable.Dos encabezados tienen el mismo texto (sin distinguir mayúsculas). Usa el modo smart con otros headers, o extrae con otro selector.
'page' debe ser una ZoanPageSession.page está vacío fuera de un body.
  • Get Text — leer un dato suelto en vez de una tabla completa.
  • Scroll — para listados de “scroll infinito” (no paginados por botón).
  • For Each — recorrer las filas extraídas.