Перейти к основному содержимому

Методы-хуки

Данные методы работают по принципу хуков. Реализация данных методов позволяет контролировать работу парсера на разных этапах, от инициализации до уничтожения объекта

Реализация всех методов кроме parse являются опциональной

async parse(set, results)

Метод parse реализует основную логику обработки запроса и получения результата парсинга, в качестве аргументов передаются:

  • set - объект с информацией о запросе:
    • set.query - текстовая строка запроса
    • set.lvl - уровень запроса, по умолчанию 0
  • results - объект с результатами, которые необходимо заполнить и вернуть из метода parse()
    • парсер должен проверять наличие каждого ключа в объекте results и заполнять его только при наличии, таким образом оптимизируется скорость и парсятся только те данные, которые используются в формировании результата
    • results содержит ключи необходимых flat переменных со значением none, по умолчанию это означает что результат не получен, а также ключи переменных-массивов (arrays) со значением в виде пустого массива, готового для заполнения
    • results.success должен устанавливаться в значение 1 при успешной обработке запроса, по умолчанию значение 0, означающее что запрос обработан с ошибкой

Разберем на примере:

class JS_HTML_Tags extends BaseParser {
static defaultConf = {
results: {
flat: [
['title', 'Title'],
],
arrays: {
h2: ['H2 Headers List', [
['header', 'Header'],
]],
}
},
...
};

async parse(set, results) {
// Получаем содержимое HTML страницы, адрес которой был передан в запросе
const {success, data, headers} = await this.request('GET', set.query);

// Проверяем успешность и тип data, при корректной обработке HTML страниц мы должны получать тип 'string', в противном случае A-Parser возвращает объект типа Buffer
if (success && typeof data == 'string') {
let matches;

// Проверяем необходимость сбора title и сохраняем значение
if (results.title && matches = data.match(/<title[^>]*>(.*?)<\/title>/))
results.title = matches[1];

// Проверяем необходимость сбора h2
if (results.h2) {
let count = 0;
const re = /<h2[^>]*>(.*?)<\/h2>/g;
while(matches = re.exec(data)) {
// Сохраняем в цикле все найденные теги h2
results.h2.push(matches[1]);
}
}

// Уведомляем об успешности парсинга
results.success = 1;
}

// Возвращаем обработанные результаты
return results;
}
};

Обратите внимание что вы можете создавать собственные функции и методы для лучшей организации кода:

function Answer() {
return 42;
}

class JS_HTML_Tags extends BaseParser {
...

async parse(set, results) {
results = await this.doWork(set, results);
return results;
}

async doWork(set, results) {
results.answer = Answer();
return results;
}
};

async processConf?(conf)

Данный метод используется для преобразования конфига по каким либо правилам, например при использовании каптчи нам всегда необходимо использовать сессии:

async processConf(conf) {
if (conf.useCaptcha)
conf.useSessions = 1
}

async parse(set, results) {
if (conf.useSessions)
await this.login();
}

Существование данного метода обусловлено тем что A-Parser поддерживает динамические поля конфига и в рамках одного задания конфиг может иметь разные значения, такой сценарий возможен в двух случаях:

  • Использование шаблонов в полях конфигурации, например [% tools.ua.random() %] для поля User-Agent
  • Использование overrides при вызове одного парсера из другого для this.parser.request

Метод processConf вызывается однократно перед init(). Для случаев описанных выше processConf вызывается дополнительно перед обработкой каждого запроса

Основные правила применения processConf:

  • Используйте только если преобразования конфига имеет эффект на производительность
  • Имейте ввиду что init выполняется один раз, а processConf может выполняться для каждого запроса, в этом случае может быть нарушена логика, если init зависит от изменяющихся полей конфига (см. ниже)

async init?()

Метод init вызывается один раз при инициализации базового объекта парсера, служит для выполнения одноразовых действия:

  • Запуск браузера
  • Инициализация менеджера сессий с помощью метода this.sessionManager.init()
  • Подключение к базе данных и создание таблиц в БД
  • Чтение статичных данных
  • И т.д.
предупреждение

Т.к. метод вызывается один раз, все поля конфигурации, от которых зависит init() не могут быть исользованы совместно с шаблонами полей конфигурации или с overrides при вызове this.parsers.request

async destroy?()

Метод destroy вызывается один раз при завершении работы задания, необходим для корреткного уничтожение открытых ресурсов:

  • Закрытие браузера
  • Закрытие подключения к БД
  • И т.д.

async threadInit?()

Данный метод запускается при инициализации каждого потока, каждый поток представляет из себя копия базового объекта парсера с своим уникальным this.threadId, который начинается с 0 и заканчивается threads_count - 1

Основные варианты применения:

  • создание страницы (вкладки) браузера для каждого потока

async threadDestroy?()

Выполняется при завершении потока в процессе завершения задания, служит для освобождения ресурсов, выделенных для данного потока

async afterResultsProcessor?(results)

Данный метод выполняется после обработки результатов: конструктором результатов, фильтрацией и уникализацией. Основным вариантом применения является добавление запросов в очередь c помощью метода this.query.add после применения пользовательских фильтров, таким образом реализована фильтрация ссылок для перехода (followlinks) для парсера HTML::LinkExtractorHTML::LinkExtractor