Pular para o conteúdo principal

Scrapers em JavaScript: Visão geral dos recursos

Scrapers JavaScript - oferecem a possibilidade de criar seus próprios scrapers completos com lógica de qualquer complexidade, utilizando a linguagem JavaScript. Ao mesmo tempo, nos scrapers JS, você também pode usar toda a funcionalidade dos scrapers padrão.

Visão geral

Recursos

Utilizando todo o poder do A-Parser, agora é possível escrever seu próprio scraper/registrador/poster com lógica de qualquer complexidade. Para escrever o código, utiliza-se JavaScript com recursos ES6 (motor v8).

O código dos scrapers é o mais conciso possível, permitindo focar na escrita da lógica; o A-Parser cuida do processamento em múltiplas threads, rede, proxies, resultados, logs, etc. O código pode ser escrito diretamente na interface do scraper, adicionando um novo scraper no Editor de Scrapers. Também é possível usar editores externos, como o VSCode, para escrever os scrapers.

O versionamento automático é utilizado ao salvar o código do scraper através do editor integrado.

nota

O trabalho com scrapers JavaScript está disponível para as licenças Pro e Enterprise

Acesso ao Editor de scrapers JS

Se o A-Parser for utilizado remotamente, por motivos de segurança, o Editor de scrapers JS não fica disponível por padrão. Para liberar o acesso, é necessário:

  • Definir uma senha na aba Settings -> Global Settings
  • Adicionar ao config/config.txt a seguinte linha: allow_javascript_editor: 1
  • Reiniciar o A-Parser

Instruções de uso

No Editor de scrapers, criamos um novo scraper e definimos o nome do scraper. Por padrão, será carregado um exemplo simples, a partir do qual você pode começar rapidamente a criar seu próprio scraper.

nota

Se um editor externo for utilizado para escrever o código, é necessário abrir o arquivo do scraper editado na pasta /parsers/. Estrutura de arquivos do programa instalado.

Quando o código estiver pronto, salve-o e utilize-o como um scraper comum: no Editor de tarefas, selecione o scraper criado; se necessário, você pode definir os parâmetros desejados, configuração de threads, nome do arquivo, etc.

O scraper criado pode ser editado a qualquer momento. Todas as alterações relacionadas à interface aparecerão após selecionar novamente o scraper na lista de scrapers ou reiniciar o A-Parser; as alterações na lógica do scraper são aplicadas ao iniciar novamente a tarefa com o scraper.

Para cada scraper criado, um ícone padrão é exibido por padrão; você pode adicionar o seu próprio no formato png ou ico, colocando-o na pasta do scraper em /parsers/:

Princípios gerais de funcionamento

Por padrão, é criado um exemplo de um scraper simples, pronto para edição posterior.

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;
}
}

O construtor é chamado uma única vez para cada tarefa. É obrigatório definir this.defaultConf.results e this.defaultConf.results_format, os demais campos são opcionais e assumirão valores padrão.

O array this.editableConf define quais configurações podem ser alteradas pelo usuário a partir da interface do A-Parser. Os seguintes tipos de campos podem ser usados:

  • combobox - menu suspenso de seleção. Também é possível criar um menu de seleção de preset de um scraper padrão, por exemplo:
['Util_AntiGate_preset', ['combobox', 'AntiGate preset']]
  • combobox com possibilidade de múltipla escolha. É necessário definir adicionalmente o parâmetro {'multiSelect': 1}:
['proxyCheckers', ['combobox', 'Proxy Checkers', {'multiSelect': 1}, ['*', 'All']]]
  • checkbox - caixa de seleção, para parâmetros que podem ter apenas 2 valores (true/false)
  • textfield - campo de texto
  • textarea - campo de texto com entrada de múltiplas linhas

O método parse representa uma função assíncrona e deve retornar await para qualquer operação bloqueante (esta é a principal e única diferença de uma função comum). O método é chamado para cada consulta enviada para processamento. São obrigatoriamente passados set (hash com a consulta e seus parâmetros) e results (um modelo vazio para os resultados). Também é obrigatório retornar o results preenchido, após definir previamente a flag success.

Versionamento automático

A versão tem o formato Major.Minor.Revision

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

O valor de Revision (o último dígito) é incrementado automaticamente a cada salvamento. Os outros valores (Major, Minor) podem ser alterados manualmente, assim como o Revision pode ser resetado para 0.

dica

Se por algum motivo for necessário alterar o Revision apenas manualmente, a versão deve ser colocada entre aspas duplas ""

Processamento de consultas em lote

Em alguns casos, pode ser necessário obter várias consultas da fila de uma só vez e processá-las de uma única vez. Esse modo é utilizado nos scrapers integrados quando, em uma única passagem, é necessário solicitar dados para várias chaves simultaneamente (em lote).

Para implementar essa mesma funcionalidade em um scraper JS, é necessário definir em this.defaultConf o valor bulkQueries: N, onde N é a quantidade necessária de consultas no lote. Nesse caso, o scraper pegará as consultas em lotes de N unidades e todas as consultas da iteração atual estarão contidas no array set.bulkQueries (incluindo todas as variáveis padrão: query.first, query.orig, query.prev, etc.). Abaixo, um exemplo de tal array:

[
{
"first": "test",
"prev": "",
"lvl": 0,
"num": 0,
"query": "test",
"queryUid": "6eb301",
"orig": "test"
},
{
"first": "verificação",
"prev": "",
"lvl": 0,
"num": 1,
"query": "verificação",
"queryUid": "774563",
"orig": "verificação"
},
{
"first": "third query",
"prev": "",
"lvl": 0,
"num": 2,
"query": "third query",
"queryUid": "2bc8ed",
"orig": "third query"
}
]

Os resultados no processamento em lote devem ser preenchidos no array results.bulkResults, onde cada elemento é um objeto results. Os elementos em results.bulkResults estão localizados na mesma ordem em que estavam em set.bulkQueries.