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

Описание методов

Новое JavaScript API v2 призвано упростить работу за счет отказа от использования генераторов в пользу async/await. Также в данном API были устранены некоторые ограничения предыдущей версии, добавлена поддержка TypeScript и повышена производительность. Мы рекомендуем использовать данное JavaScript API для создания всех новых парсеров

Для использования JavaScript API v2 достаточно наследовать свой класс парсера от базового BaseParser. Разберем на примере структуру класса парсера:

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', 'Title'],
['h1', 'H1 Header']
],
arrays: {
h2: ['H2 Headers List', [
['header', 'Header'],
]],
}
},
max_size: 2 * 1024 * 1024,
parsecodes: {
200: 1,
},
results_format: "Title: $title\nH1: $h1\nH2 headers:\n$h2.format('$header\\n')\n",
limitH2Tags: 3,
};
static editableConf: typeof BaseParser.editableConf = [
['limitH2Tags', ['textfield', 'Limit H2 tags']],
];
async parse(set, results) {
const {success, data, headers} = await this.request('GET', set.query);
if(success && typeof data == 'string') {
let matches;
if(matches = data.match(/<title[^>]*>(.*?)<\/title>/))
results.title = matches[1];
if(matches = data.match(/<h1[^>]*>(.*?)<\/h1>/))
results.h1 = matches[1];
if(results.h2) {
let count = 0;
const re = /<h2[^>]*>(.*?)<\/h2>/g;
while(matches = re.exec(data)) {
results.h2.push(matches[1]);
if(++count == this.conf.limitH2Tags)
break;
}
}
}
return results;
}
}

Отличия от API v1#

  • Генераторы заменены на async/await
  • Поля defaultConf и editableConf стали static
  • Класс парсера должен быть наследован от BaseParser
  • TypeScript может быть использован опционально, мы рекомендуем использовать его по умолчанию для подсветки доступных методов и параметров

Использование TypeScript#

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

typescript

Мы рекомендуем использовать редактор Visual Studio Code для создания и редактирования парсеров

Установите библиотеку типов A-Parser:

cd files/
npm install a-parser-types

A-Parser автоматически создает базовый конфигурационный файл TypeScript при его отсутствии:

files/tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"moduleResolution": "node",
"module": "commonjs",
"sourceMap": true,
"baseUrl": ".",
"paths": {
"*": ["node_modules/*", "../dist/nodejs/node_modules/*"]
}
},
"include": ["**/*.ts"]
}

Создайте файл парсера:

mkdir files/parsers/Awesome-Parser/
touch files/parsers/Awesome-Parser/Awesome-Parser.ts

Используйте данный шаблон для начала разработки:

files/parsers/Awesome-Parser/Awesome-Parser.ts
import { BaseParser } from 'a-parser-types';
export class JS_Awesome_Parser extends BaseParser {
static defaultConf: typeof BaseParser.defaultConf = {
version: '0.0.1',
results: {
flat: [
['title', 'Title'],
],
arrays: {
}
},
results_format: "Title: $title\n",
};
static editableConf: typeof BaseParser.editableConf = [
];
async parse(set, results) {
...
return results;
}
}
info

A-Parser автоматически скомпилирует .ts файлы в .js перед запуском парсера

Поля конфигурации#

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

static defaultConf#

static defaultConf = {
version: '0.0.1',
results: {
flat: [
['title', 'Title'],
],
arrays: {
}
},
results_format: "Title: $title\n",
exampleKey: 'value',
};

Конфигурация парсера по умолчанию, конфиг будет доступен в объекте класса через свойство this.conf, обязательными являются следующие поля:

  • results - описывает в декларативном стиле результаты, которые может возвращать данный парсер

  • results_format - задает формат результата по умолчанию

Все остальные поля являются опциональными, существует следующий список параметров, которые влияют на работу парсера:

Название параметраТипОписание(значение по умолнанию)
timeoutnumberМаксимальное время ожидания запроса в секундах(60)
useproxyboolean / 0 / 1Определяет использовать ли прокси(1)
max_sizenumberМаксимальный размер файла результата(1 * 1024 * 1024)
proxyretriesnumberКоличество попыток на каждый запрос, если запрос не удаётся выполнить за указанное число попыток то он считается неудачным и пропускается(10)
requestdelaynumberЗадержка между запросами в секундах(0)
proxybannedcleanupnumberВремя бана прокси в секундах(600)
pagecountnumberКоличество страниц парсинга(1)
parsecodes { [code: string]: any },Значение кодов ответов для запросов которые будут считаться успешными(any)
queryformatstringФормат запроса($query)
info

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

static editableConf#

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

  • textfield - поле для произвольного ввода числовых и строковых значений
  • checkbox - флаг с состояниями включен/выключен
  • combobox - дропдаун с выбором одного или нескольких значений
  • выбор нескольких значений задается через опцию { multiSelect: 1 }

editableConf представляет из собой массив, каждый элемент которого описывает соответсвующее поле конфигурации:

static editableConf: [
...[
fieldName: string,
fieldConfig: [
fieldType: 'textfield' | 'combobox' | 'checkbox',
fieldLabel: string,
fieldOptions?: {},
...fieldValues: [fieldValue: any, valueTitle: string][]
]
][]
];

Пример объявления редактируемых полей:

static get editableConf() {
let editableConf: typeof BaseParser.editableConf = [
['device',
['combobox', 'Device',
['desktop', 'Modern desktop computer (Windows 10, Chrome 84)'],
['mobile', 'Mobile device (iPhone X, iOS 11)']
]
],
['pagecount', ['combobox', 'Pages count']],
['linksperpage',
['combobox', 'Links per page',
[10, '10'],
[20, '20'],
[30, '30'],
[50, '50']
]
],
];
for (let page = 1; page <= 25; page++)
editableConf[1][1].push([page, page]);
return editableConf;
}

скрин интерфейса, где показаны настройки из пресета выше

note

Обратите внимание, в данном примере использован метод-геттер для editableConf, что позволяет производить дополнительную обработку, например генерацию списка страниц. Для более простых случаев вы можете задавать статичное свойства класса, аналогично как и для defaultConf

static parserOptions#

parserOptions является альтернативным вариантом задания настроек, список опций отображается как дополнительные пункты в контекстном меню парсера

скрин где видно опции парсера в контекстном меню

Декларирование опций работает аналогично editableConf:

static parserOptions: [
...[
fieldName: string,
menuTitle: string,
fieldConfig: [
fieldType: 'textfield' | 'combobox' | 'checkbox',
fieldLabel: string,
fieldOptions?: {},
...fieldValues: [fieldValue: any, valueTitle: string][]
]
][]
];

Пример:

static parserOptions: typeof BaseParser.parserOptions = [
['parseAll', 'Parse all results',
['checkbox', 'Parse all results']
],
['parseLevel', 'Parse related to level',
['combobox', 'Parse Related to level', [1, 1], [2, 2], [3, 3]]
],
];

Реализация методов-хуков#

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

Реализация всех методов кроме 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 поддерживает динамические поля конфига и в рамках одного задания конфиг может иметь разные значения, такой сценарий возможен в 2ух случаях:

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

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

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

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

async init?()#

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

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

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

async destroy?()#

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

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

async threadInit?()#

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

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

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

async threadDestroy?()#

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

async afterResultsProcessor?(results)#

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

Методы базового класса#

Данные методы наследуются от BaseParser и являются основой для создания собственных парсеров

await this.request(method, url[, queryParams][, opts])#

await this.request(method, url, queryParams, opts)

Получение HTTP ответа по запросу, в качестве аргументов указывается:

  • method - метода запроса (GET, POST...)
  • url - ссылка для запроса
  • queryParams - хэш с get параметрами или хэш с телом post-запроса
  • opts - хэш с опциями запроса

Если используется метод POST, то тело запроса можно передать двумя способами:

  • просто перечислив названия переменных и их значения в queryParams. Например:
{
key: set.query,
id: 1234,
type: 'text'
}
  • через переменную body в opts. Например:
body: 'key=' + set.query + '&id=1234&type=text'

opts.check_content#

check_content: [ условие1, условие2, ...] - массив условий для проверки получаемого контента, если проверка не проходит, то запрос будет повторен с другим прокси.

Возможности:#

  • использование в качестве условий строк (поиск по вхождению строки)
  • использование в качестве условий регулярных выражений
  • использование своих функций проверок, в которые передаются данные и хедеры ответа
  • можно задать сразу несколько разных типов условий
  • для логического отрицания поместите условие в массив, т.е. check_content: ['xxxx', [/yyyy/]] означает что запрос будет считаться успешным, если в полученных данных содержится подстрока xxxx и при этом регулярное выражение /yyyy/ не находит совпадений на странице

Для успешного запроса должны пройти все указанные в массиве проверки

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

let response = await this.request('GET', set.query, {}, {
check_content: [
/<\/html>|<\/body>/, //на полученной странице должно сработать это регулярное выражение
['XXXX'], //на полученной странице не должно быть этой подстроки
'</html>', //на полученной странице должна быть такая подстрока
(data, hdr) => {
return hdr.Status == 200 && data.length > 100;
} //эта функция должна вернуть true
]
});

opts.decode#

decode: 'auto-html' - автоматическое определение кодировки и преобразование в utf8

Возможные значения:

  • auto-html - на основе заголовков, тегов meta и по содержимому страници (оптимальный рекомендуемый вариант)
  • utf8 - указывает что документ в кодировке utf8
  • <encoding> - любая другая кодировка

opts.headers#

headers: { ... } - хэш с заголовками, название заголовка задается в нижнем регистре, можно указать в т.ч. cookie Пример:

headers: {
accept: 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
'accept-encoding': 'gzip, deflate, br',
cookie: 'a=321; b=test',
'user-agent' 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'
}

opts.headers_order#

headers_order: ['cookie', 'user-agent', ...] - позволяет переопределить порядок сортировки заголовков

opts.recurse#

recurse: N - максимальное число переходов по редиректам, по умолчанию 7, используйте 0 для отключения перехода по редиректам

opts.proxyretries#

proxyretries: N - число попыток выполнения запроса, по умолчанию берется из настроек парсера

opts.parsecodes#

parsecodes: { ... } - перечень кодов HTTP ответов, которые парсер будет считать удачными, по умолчанию берется из настроек парсера. Если указать '*': 1 то все ответы будут считаться удачными. Пример:

parsecodes: {
200: 1,
403: 1,
500: 1
}

opts.timeout#

timeout: N - таймаут ответа в секундах, по умолчанию берется из настроек парсера

opts.do_gzip#

do_gzip: 1 - определяет использовать ли компрессию (gzip/deflate/br), по умолчанию включено (1), для выключения нужно задать значение 0

opts.max_size#

max_size: N - максимальный размер ответа в байтах, по умолчанию берется из настроек парсера

opts.cookie_jar#

cookie_jar: { ... } - хэш с куками. Пример хэша:

"cookie_jar": {
"version": 1,
".google.com": {
"/": {
"login": {
"value": "true"
},
"lang": {
"value": "ru-RU"
}
}
},
".test.google.com": {
"/": {
"id": {
"value": 155643
}
}
}
}

opts.attempt#

attempt: N - указывает на номер текущей попытки, при использовании этого параметра встроенный обработчик попыток для данного запроса игнорируется

opts.browser#

browser: 1 - автоматическая эмуляция заголовков браузера (1 - включено, 0 - выключено)

opts.use_proxy#

use_proxy: 1 - переопределяет использование прокси для отдельного запроса внутри JS парсера поверх глобального параметра Use proxy (1 - включено, 0 - выключено)

opts.noextraquery#

noextraquery: 0 - отключает добавление Extra query string к урлу запроса (1 - включено, 0 - отключено)

opts.save_to_file#

save_to_file: file - позволяет скачать файл напрямую на диск, минуя запись в память. Вместо file указывается имя и путь под каким сохранить файл. При использовании этой опции игнорируется все, что связано с data (проверка контента в check_content, response.data будет пустой и т.д.).

opts.needData#

needData: 1 - определяет передавать (1) или нет (0) в ответе data/pages[], может использоваться для оптимизации

opts.data_as_buffer#

data_as_buffer: 0 - определяет возвращать data как строку String (0) или как объект Buffer (1), по умолчанию возвращается строка String

opts.bypass_cloudflare#

bypass_cloudflare: 0 - автоматический обход JavaScript защиты CloudFlare используя браузер Chrome (1 - включено, 0 - выключено)

opts.follow_meta_refresh#

follow_meta_refresh: 0 - позволяет переходить по редиректам, объявленным через HTML мета тег:

<meta http-equiv="refresh" content="time; url=..." />

opts.tlsOpts#

tlsOpts: { ... } – позволяет передавать настройки для https соединений ​

await this.parser.request(parser, preset, overrideParams, query)#

await this.parser.request(parser, preset, overrideParams, query)

Получение результатов от другого парсера (встроенного или еще другого JS парсера), в качестве аргументов указывается

  • parser - имя парсера (SE::Google, JS::Custom::Example)
  • preset - пресет настроек вызываемого парсера
  • overrideParams - хэш с переопределениями настроек вызываемого парсера
  • query - запрос

В overrideParams, кроме параметров вызываемого парсера, дополнительно можно передать флаг resultArraysWithObjects: 1 - он позволяет возвращать массив объектов в результатах вместо стандартного массива значений

Пример:

import { BaseParser } from 'a-parser-types';
class JS_DocExample extends BaseParser {
static defaultConf: typeof BaseParser.defaultConf = {
results_format: "$links.format('$link\n')",
results: {
flat: [
['title', 'Title'],
],
arrays: {
links: ['Links', [
['link', 'link'],
]],
}
}
}
async parse(set, results) {
let response = await this.parser.request('SE::Google', 'default', {
resultArraysWithObjects: 1,
proxyretries: 100,
pagecount: 1
}, set.query)
if (response.success) {
response.serp.forEach(element => {
results.links.push(element.link);
});
}
results.success = 1;
return results;
}
}

Пример результата:

https://www.speedtest.net/
https://www.investopedia.com/terms/t/t-test.asp
https://www.cdc.gov/coronavirus/2019-ncov/testing/diagnostic-testing.html
https://fast.com/
https://www.thinkwithgoogle.com/feature/testmysite/
https://projectstream.google.com/speedtest
https://www.nhs.uk/conditions/coronavirus-covid-19/testing/
https://www.fda.gov/consumers/consumer-updates/coronavirus-disease-2019-testing-basics
https://zoom.us/test
https://www.gov.uk/get-coronavirus-test
https://en.wikipedia.org/wiki/Test_(assessment)
https://implicit.harvard.edu/
https://www.merriam-webster.com/dictionary/test
https://www.att.com/support/speedtest/
https://www.test.com/
https://www.16personalities.com/free-personality-test
https://www.khanacademy.org/test-prep/sat
https://www.cambridgeenglish.org/test-your-english/
https://developers.google.com/speed/pagespeed/insights/
https://www.bemindfulonline.com/test-your-stress
https://search.google.com/test/mobile-friendly
https://help.blackboard.com/Learn/Instructor/Tests_Pools_Surveys/Test_and_Survey_Options
https://www.ets.org/toefl
https://www.efset.org/
https://collegereadiness.collegeboard.org/sat/register/dates-deadlines
https://en.wikipedia.org/wiki/Test_method
https://www.facebook.com/business/help/2040882565969969
https://www.123test.com/career-test/
...

await tools.*#

Глобальный объект tools, позволяет получить доступ к встроенным функциям A-Parser'а (аналог инструментов шаблонизатора $tools.*).

important

tools.query не доступен, необходимо использовать this.query

this.doLog()#

Показывает включено ли ведение лога задания, может использоваться как флаг для оптимизации, для случаев когда лог не ведется и аргументом к this.logger.put идет сложное выражение

this.logger.*#

.put(message)#

this.logger.put(message) - добавляет строчку message в лог задания

.putHTML(HTML)#

this.logger.putHTML(code) - вывод в лог задания HTML кода, который будет отображен в textarea

await this.sleep(sec)#

await this.sleep(sec)

Устанавливает задержку в потоке на число секунд sec, может быть дробным.

await this.mutex.*#

Мютекс для синхронизации между потоками, позволяет заблокировать секцию кода для одного потока

.lock()#

Ожидание лока, исполнение продолжит первый поток, который захватил лок, остальные потоки будут ожидать освобождение лока

.unlock()#

Освобождение лока, следующий поток продолжит выполнение, если он ожидал лок(.lock())

await this.cookies.*#

Работа с cookies для текущего запроса

.getAll()#

Получение массива cookies

await this.cookies.getAll();

пример результата получения массива cookies

.setAll(cookie_jar)#

Установка cookies, в качестве аргумента должен быть передан массив с cookies

async parse(set, results) {
this.logger.put("Start scraping query: " + set.query);
await this.cookies.setAll(['test_1=1', 'test_2=2']);
let cookies = await this.cookies.getAll();
this.logger.put("Cookies: " + JSON.stringify(cookies));
results.SKIP = 1;
return results;
}

пример результата установки массива cookies

.set(host, path, name, value)#

await this.cookies.set(host, path, name, value) - установка одиночного cookie

async parse(set, results) {
this.logger.put("Start scraping query: " + set.query);
await this.cookies.set('.a-parser.com', '/', 'Test-cookie-1', 1);
await this.cookies.set('.a-parser.com', '/', 'Test-cookie-2', 'test-value');
let cookies = await this.cookies.getAll();
this.logger.put("Cookies: " + JSON.stringify(cookies));
results.SKIP = 1;
return results;
}

пример результата установки одиночного cookie

await this.query.add(query, maxLvl)#

await this.query.add(query, maxLvl)

Добавление нового запроса (query) с возможностью опционально указать максимальный уровень (maxLvl), аналогично tools.query.add() Можно передавать в качестве запроса (query) хэш с параметрами, работает аналогично Конструктору запросов

Пример:

this.query.add({
query: "http://site.com",
param1: "..",
...
});

await this.proxy.*#

Работа с прокси

.next()#

Сменить прокси на следующий, старый прокси больше не будет использован для текущего запроса

.ban()#

Сменить и забанить прокси (необходимо использовать когда сервис блокирует работу по IP), прокси будет забанен на время, указанное в настройках парсера(proxybannedcleanup)

.get()#

Получить текущий прокси (последний прокси с которым был сделан запрос)

.set(proxy[, noChange])#

await this.proxy.set('http://127.0.0.1:8080', true) - установить прокси для следующего запроса, параметр noChange необязательный, если задан true то прокси не будет меняться между попытками. По умолчанию noChange = false

await this.captcha.*#

Работа с каптчей

.recognize(preset, image, type[, overrides])#

await this.captcha.recognize(preset, image, type, overrides) - загрузка каптчи для распознавания

  • image - бинарные данные картинки для распознавания
  • preset - указывает на пресет для Util::AntiGateUtil::AntiGate
  • type указывается один из: 'jpeg', 'gif', 'png'

Результатом будет хэш с полями:

  • answer - текст из картинки
  • id - id каптчи, для возможности в дальнейшем сообщить об ошибке через reportBad
  • error - текстовая ошибка, если answer не задан

.recognizeFromUrl(preset, url[, overrides])#

await this.captcha.recognizeFromUrl(preset, url, overrides) - аналогично предыдущему методу, но загрузка каптчи будет выполнятся автоматически по ссылке (url), без использования прокси

.reportBad(preset, id[, overrides])#

await this.captcha.reportBad(preset, id, overrides) - сообщить сервису что каптча разгадана неверно

this.utils.*#

.updateResultsData(results, data)#

await this.utils.updateResultsData(results, data) - метод для автоматического заполнения $pages.$i.data и $data, необходимо вызывать для добавления контента результирующей страницы

.urlFromHTML(url, base)#

await this.utils.urlFromHTML(url, base) - обрабатывает ссылку полученную из HTML кода - декодирует entities (&amp; и т.п.), опционально можно передавать base - базовый урл (например урл исходной страницы), таким образом может быть получена полная ссылка

.url.extractDomain(url, removeDefaultSubdomain)#

await this.utils.url.extractDomain(url, removeDefaultSubdomain) - метод принимает в качестве первого параметра ссылку и возвращает домен из этой ссылки. Второй необязательный параметр определяет обрезать ли из домена субдомен www. По умолчанию 0 - то есть не обрезать.

.url.extractTopDomain(url)#

await this.utils.url.extractTopDomain(url) - метод принимает в качестве первого параметра ссылку и возвращает домен из этой ссылки, без субдоменов.

.url.extractTopDomainByZone(url)#

await this.utils.url.extractTopDomainByZone(url) - метод принимает в качестве первого параметра ссылку и возвращает домен из этой ссылки, без субдоменов в том числе. Работает cо всеми региональными зонами

.url.extractMaxPath(url)#

await this.utils.url.extractMaxPath(url) - метод принимает строку и выбирает из нее урл

.url.extractWOParams(url)#

await this.utils.url.extractWOParams(url)- метод принимает ссылку и возвращает эту же ссылку обрезанную до строки параметров. То есть вернет урл до ?

.removeHtml(string)#

await this.utils.removeHtml(string) - метод принимает строку и возвращает её очищенной от html тегов

.removeNoDigit(string)#

await this.utils.removeNoDigit(string) - метод принимает строку, удаляет из неё все кроме цифр и возвращает результат

.removeComma(string)#

await this.utils.removeComma(string) - метод принимает строку, удаляет из неё такие символы как .,\r\n и возвращает результат

await this.sessionManager.*#

.init(opts)#

Для использования сессий в JS парсере сначала нужно инициализировать Менеджер сессий. Делается это с помощью функции init()

async init() {
await this.sessionManager.init({
//здесь можно задать дополнительные параметры
});
}

В this.sessionManager.init() можно использовать следующие параметры:

  • name - необязательный параметр, позволяет переопределить имя парсера, которому принадлежат сессии, по-умолчанию равно имени парсера, в котором происходит инициализация
  • canChangeProxy - необязательный параметр, возможность менять прокси, по-умолчанию равно 1
  • domain - необязательный параметр, указывает искать сессии среди всех сохраненных для этого парсера (если значение не задано), или же только для конкретного домена (необходимо указывать домен с точкой спереди, например .site.com)

Для работы с сессиями существует несколько функций:

.get()#

await this.sessionManager.get() - получает новую сессию, необходимо вызывать перед осуществлением запроса

.reset()#

await this.sessionManager.reset() - очистка куков и получение новой сессии. Необходимо вызывать, если с текущей сессией запрос не был удачным.

.save()#

await this.sessionManager.save() - сохранение удачной сессии либо сохранение произвольных данных в сессии

Пример сохранения произвольных данных и дальнейшего их получения:

async init() {
await this.sessionManager.init({
//здесь можно задать дополнительные параметры
});
}
async parse(set, results) {
this.logger.put("Start scraping query: " + set.query);
let ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)';
let referer = set.query;
let data = 'Some data';
await this.sessionManager.save({ua, referer, data});
let session = await this.sessionManager.get();
this.logger.put("Session: " + JSON.stringify(session));
results.SKIP = 1;
return results;
}

пример сохранения произвольных данных и дальнейшего их получения

results.<array>.addElement()#

Метод results.<array>.addElement() позволяет более удобно заполнять массивы в results. При его использовании не нужно помнить последовательность переменных в массиве и перечислять их вручную.

results.serp.addElement({
link: 'https://google.com',
anchor: 'Google',
snippet: 'Loreps ipsum...',
});

Полезные ссылки#

Пример сохранения файла на диск

Пример, демонстрирующий способ сохранения файлов напрямую на диск

Пример работы с сессиями

Использование функционала сессий в JavaScript парсерах

Пример сохранения данных в сессии

Демонстрация возможности хранить произвольные данные в сессии

Использование results.addElement()

Пример заполнения массива данных с помощью results.addElement() и демонстрация отличия от обычного .push()

Последнее обновление