JavaScript парсеры

15 май 2017
  • JavaScript парсеры - это возможность создавать собственные полноценные парсеры со сколько угодно сложной логикой, используя JavaScript. При этом в JS парсерах можно также использовать весь функционал стандартных парсеров.
    [​IMG]


    Особенности(top)


    • Используя всю мощь A-Parser теперь можно написать свой парсер/регер/постер со сколько угодно сложной логикой
    • Для написания кода используется JavaScript с возможностями ES6 (движок v8)
    • Код парсеров максимально лаконичен, позволяет сосредоточится на написании логики; работу с многопоточностью, сетью, прокси, результатами, логами и т.д. A-Parser берет на себя
    • Код можно писать прямо в интерфейсе парсера, добавив новый парсер в Редакторе парсеров, по умолчанию будет загружен простой пример, на основе которого можно быстро приступить к созданию собственного парсера
    • Используется автоматическое версионирование при сохранении кода парсера через встроенный редактор
    • Доступно для лицензий Pro и Enterprise, для всех ОС кроме linux 32bit

    Инструкция по работе(top)


    • В Редакторе парсеров создаем новый парсер
    • Задаем имя парсера
    • Пишем код парсера
    • Сохраняем и используем как обычный парсер: в Редакторе заданий выбираем созданный парсер, при необходимости можно задать нужные параметры, конфиг потоков, имя файла и т.п.
    • Созданный парсер можно в любой момент редактировать. Все изменения, касающиеся интерфейса появятся после повторного выбора парсера в списке парсеров или перезапуска А-Парсера; изменения в логике парсера применяются при повторном запуске задания с парсером
    • По-умолчанию отображается стандартная иконка, можно добавить свою в формате png или ico:
      [​IMG]

    Документация(top)

    JS парсеры на данный момент в процессе частых изменений и добавления функционала, поэтому данный раздел будет обновляться и меняться по мере появления изменений в функционала JavaScript парсеров

    1. Общие принципы работы
    • Конструктор вызывается однократно для каждого задания
      • Необходимо обязательно задать this.defaultConf.results и this.defaultConf.results_format, остальные поля необязательны и будут принимать значения по-умолчанию
      • Массив this.editableConf определяет какие настройки могут быть изменены пользователем из интерфейса A-Parser
        • Можно использовать следующие типы полей:
          • combobox - выпадающее меню выбора. Также можно сделать меню выбора пресета стандартного парсера, например:
            Код:
            ['Util_AntiGate_preset', ['combobox', 'AntiGate preset']]
          • checkbox - чекбокс, для параметров которые могут иметь только 2 значения (true/false)
          • textfield - текстовое поле
    • Метод *parse представляет собой генератор, и на любую блокирующую операцию должен возвращать yield (это основное и единственное отличие от обычной функции)
      • Метод вызывается для каждого запроса поступившего в обработку
      • Передается set (хэш с запросом и его параметрами) и results (пустая заготовка для результатов)
      • Необходимо обязательно вернуть заполненый results, предварительно выставив флаг success

    2. Автоматическое версионирование
    Код:
            this.defaultConf = {
                version: '0.1.1',
    
    • Версия имеет формат: Major.Minor.Revision
    • Значение Revision (последняя цифра) автоматически увеличивается при каждом сохранении
    • Остальные значения (Major, Minor) можно менять вручную, а также сбрасывать Revision в 0
    • Если по каким то причинам необходимо менять Revision только вручную, то версию необходимо заключить в двойные кавычки ""

    3. yield this.request(method, url, queryParams, opts)
    • Получение HTTP ответа по запросу, в качестве аргументов указывается method, url, хэш с query параметрами, хэш с опциями запроса
    • Доступные опции(opts):
      • check_content: ['<\/html>'] - массив регулярок для проверки, если проверка не проходит запрос будет повторен с другим прокси
      • decode: 'auto-html' - автоматическое определение кодировки и преобразование в utf8, возможные значения: auto-html (на основе заголовков, тегов meta и по содержимому странички, оптимальный вариант), utf8 (указывает что документ в кодировке utf8)
      • headers: {'user-agent': 'Google bot'} - хэш с заголовками, название заголовка задается в нижнем регистре, можно указать в т.ч. cookie
      • headers_order: ['cookie', 'user-agent', ...] - позволяет переопределить порядок заголовков
      • recurse: 0 - максимальное число переходов по редиректам, по умолчанию 7
      • proxyretries: 10 - число попыток, по умолчанию берется из настроек парсера
      • parsecodes: {200: 1} - перечень удачных HTTP ответов, если указан '*': 1 то все ответы удачные, по умолчанию берется из настроек парсера
      • timeout: 30 - таймаут ответа в секундах
      • do_gzip: 1 - определяет использовать ли компрессию, по умолчанию включено
      • max_size: 4096 - максимальный размер ответа в байтах, по умолчанию берется из настроек парсера
      • cookie_jar: { } - хэш с куками (формат будет разобран ниже)
      • attempt: 3 - указывает на номер текущей попытки, при использовании этого параметра встроенный обработчик попыток для данного запроса игнорируется
      • browser: 1 - автоматическая эмуляция заголовков браузера

    4. yield this.parser.request(parser, preset, overrideParams, query)
    • Получение результатов от другого (стандартного) парсера, в качестве аргументов указывается название парсера, его пресет, хэш override(опционально), запрос

    5. tools.*
    • Глобальный объект tools, позволяет получить доступ к встроенным функциям A-Parser'а, а также к tools.js (tools.query не доступен, необходимо использовать this.query)

    6. this.logger.*
    • Метод this.logger.put отображает строчку в логе
    • this.logger.doLog может использоваться как флаг для оптимизации, для случаев когда лог не ведется и аргументом к .put идет сложное выражение

    7. yield this.sleep(sec)
    • Устанавливает задержку в потоке на число секунд, может быть дробным

    8. yield this.mutex.lock(), yield.this.mutex.unlock()
    • Мютекс для синхронизации между потоками, позволяет заблокировать секцию кода для одного потока, пример в парсере JS::Rank::MOZ

    9. this.cookies.*
    • Работа с cookies
      • this.cookies.getAll() - получение массива cookies
      • this.cookies.setAll(cookies) - установка cookies, в качестве аргумента должен быть передан массив с cookies
      • this.cookie.set(host, path, name, value) - установка одиночного cookies

    10. this.query.add(query, maxLvl)
    • Добавление нового запроса с возможностью опционально указать максимальный уровень (аналогично tools.query.add)

    11. this.proxy.*
    • Работа с прокси
      • this.proxy.next() - сменить прокси, старый прокси больше не будет использован для текущего запроса
      • this.proxy.ban() - сменить и забанить прокси (необходимо использовать когда сервис блокирует работу по IP)
      • this.proxy.get() - получить текущий прокси (последний прокси с которым был сделан запрос)
      • this.proxy.set('http://127.0.0.1:8080', noChange = false) - установить прокси для следующего запроса, параметр noChange необязательный, если задан true то прокси не будет меняться между попытками

    12. yield this.captcha.*
    • Работа с каптчей
      • yield this.captcha.recognize(preset, image, type, overrides) - загрузка каптчи для распознавания, image - бинарные данные картинки для распознавания, preset указывает на пресет для Util::AntiGate Util::AntiGate, type указывается один из: 'jpeg', 'gif', 'png', результатом будет хэш с полями answer (если задан - это текст картинки), id (id каптчи, для возможности в дальнейшем сообщить об ошибке через reportBad), error (текстовая ошибка, если answer не задан)
      • yield this.captcha.recognizeFromUrl(preset, url, overrides) - аналогично предыдущему методу, но загрузка каптчи будет выполнятся автоматически по ссылке, без использования прокси
      • yield this.captcha.reportBad(preset, id, overrides) - сообщить сервису что каптча разгадана неверно

    13. this.util.*
    • this.util.updateResultsData(results, data) - метод для автоматического заполнения $pages.$i.data и $data, необходимо вызывать для добавления контента результирующей страницы
    • this.util.urlFromHTML(url, [base]) - обрабатывает ссылку полученную из HTML кода - декодирует entities (&amp; и т.п.), опционально можно передавать base - базовый урл (например урл исходной страницы), таким образом может быть получена полная ссылка

    Полезные ссылки(top)