Ir al contenido principal

Extractores en JavaScript: Resumen de capacidades

Los extractores JavaScript son una oportunidad para crear sus propios extractores completos con una lógica de cualquier complejidad, utilizando el lenguaje JavaScript. Al mismo tiempo, en los extractores JS también se puede utilizar toda la funcionalidad de los extractores estándar.

Resumen

Características

Utilizando todo el poder de A-Parser, ahora es posible escribir su propio extractor/registrador/poster con una lógica de cualquier complejidad. Para escribir el código se utiliza JavaScript con capacidades de ES6 (motor v8).

El código de los extractores es lo más conciso posible, permitiendo enfocarse en la escritura de la lógica; el trabajo con el multihilo, la red, los proxies, los resultados, los registros, etc., A-Parser lo asume por sí mismo. El código se puede escribir directamente en la interfaz del extractor, añadiendo un nuevo extractor en el Editor de extractores. También se pueden utilizar editores externos para escribir extractores, como VSCode.

Se utiliza el versionado automático al guardar el código del extractor a través del editor integrado.

nota

El trabajo con extractores JavaScript está disponible para las licencias Pro y Enterprise

Acceso al Editor de extractores JS

Si A-Parser se utiliza de forma remota, por razones de seguridad el Editor de extractores JS no está disponible por defecto. Para habilitar el acceso, es necesario:

  • Establecer una contraseña en la pestaña Settings (Configuración) -> Global Settings (Configuración general)
  • Añadir en config/config.txt la siguiente línea: allow_javascript_editor: 1
  • Reiniciar A-Parser

Instrucciones de trabajo

En el Editor de extractores creamos un nuevo extractor y definimos el nombre del extractor. Por defecto se cargará un ejemplo sencillo, sobre el cual se puede comenzar rápidamente a crear su propio extractor.

nota

Si se utiliza un editor externo para escribir el código, se debe abrir el archivo del extractor que se está editando en la carpeta /parsers/. Estructura de archivos del programa instalado.

Cuando el código esté listo, lo guardamos y lo usamos como un extractor normal: en el Editor de tareas seleccionamos el extractor creado, si es necesario se pueden definir los parámetros requeridos, la configuración de hilos, el nombre del archivo, etc.

El extractor creado se puede editar en cualquier momento. Todos los cambios relacionados con la interfaz aparecerán después de volver a seleccionar el extractor en la lista de extractores o reiniciar A-Parser; los cambios en la lógica del extractor se aplican al volver a ejecutar la tarea con el extractor.

Para cada extractor creado se muestra por defecto un icono estándar, se puede añadir uno propio en formato png o ico, colocándolo en la carpeta del extractor en /parsers/:

Principios generales de funcionamiento

Por defecto se crea un ejemplo de un extractor sencillo, listo para su posterior edición.

files/parsers/v2-example/v2-example.ts

import { BaseParser } from 'a-parser-types';

export class JS_v2_example extends BaseParser {
static defaultConf: typeof BaseParser.defaultConf = {
version: '0.0.1',
results: {
flat: [
['title', 'HTML title'],
]
},
max_size: 2 * 1024 * 1024,
parsecodes: {
200: 1,
},
results_format: '$query: $title\\n',
};

static editableConf: typeof BaseParser.editableConf = [];

async parse(set, results) {
this.logger.put("Start scraping query: " + set.query);

let response = await this.request('GET', set.query, {}, {
check_content: ['<\/html>'],
decode: 'auto-html',
});

if (response.success) {
let matches = response.data.match(/<title>(.*?)<\/title>/i);
if (matches)
results.title = matches[1];
}

results.success = response.success;

return results;
}
}

El constructor se llama una sola vez para cada tarea. Es obligatorio definir this.defaultConf.results y this.defaultConf.results_format, los demás campos son opcionales y tomarán valores por defecto.

El array this.editableConf determina qué configuraciones pueden ser modificadas por el usuario desde la interfaz de A-Parser. Se pueden utilizar los siguientes tipos de campos:

  • combobox - menú desplegable de selección. También se puede crear un menú de selección de ajuste preestablecido de un extractor estándar, por ejemplo:
['Util_AntiGate_preset', ['combobox', 'AntiGate preset']]
  • combobox con posibilidad de selección múltiple. Se debe definir adicionalmente el parámetro {'multiSelect': 1}:
['proxyCheckers', ['combobox', 'Proxy Checkers', {'multiSelect': 1}, ['*', 'All']]]
  • checkbox - casilla de verificación, para parámetros que solo pueden tener 2 valores (true/false)
  • textfield - campo de texto
  • textarea - campo de texto con entrada multilínea

El método parse es una función asíncrona y debe devolver await para cualquier operación de bloqueo (esta es la principal y única diferencia con una función normal). El método se llama para cada consulta que entra en procesamiento. Se pasan obligatoriamente set (hash con la consulta y sus parámetros) y results (una plantilla vacía para los resultados). También es obligatorio devolver el results completado, habiendo establecido previamente la bandera success.

Versionado automático

La versión tiene el formato Major.Minor.Revision

this.defaultConf: typeof BaseParser.defaultConf = {
version: '0.1.1',
...
}

El valor de Revision (el último dígito) aumenta automáticamente con cada guardado. Los demás valores (Major, Minor) se pueden cambiar manualmente, así como restablecer Revision a 0.

sugerencia

Si por alguna razón es necesario cambiar Revision solo manualmente, entonces la versión debe encerrarse entre comillas dobles ""

Procesamiento por lotes de consultas

En algunos casos puede ser necesario tomar varias consultas de la cola a la vez y procesarlas de un solo golpe. Este modo se utiliza en los extractores integrados cuando se necesitan solicitar datos para varias claves a la vez (en lote) en una sola pasada.

Para implementar la misma funcionalidad en un extractor JS, se debe definir en this.defaultConf el valor bulkQueries: N, donde N es la cantidad necesaria de consultas en el lote. En este caso, el extractor tomará las consultas en lotes de N unidades y todas las consultas de la iteración actual estarán contenidas en el array set.bulkQueries (incluyendo todas las variables estándar: query.first, query.orig, query.prev, etc.). A continuación, un ejemplo de dicho array:

[
{
"first": "test",
"prev": "",
"lvl": 0,
"num": 0,
"query": "test",
"queryUid": "6eb301",
"orig": "test"
},
{
"first": "comprobación",
"prev": "",
"lvl": 0,
"num": 1,
"query": "comprobación",
"queryUid": "774563",
"orig": "comprobación"
},
{
"first": "third query",
"prev": "",
"lvl": 0,
"num": 2,
"query": "third query",
"queryUid": "2bc8ed",
"orig": "third query"
}
]

Los resultados en el procesamiento por lotes deben completarse en el array results.bulkResults, donde cada elemento es un objeto results. Los elementos en results.bulkResults están ubicados en el mismo orden en que estaban en set.bulkQueries.