Фильтрация по размеру текста

Как спарсить статьи с заданного списка сайтов 1.0

Available for license holders
  • Автор темы Автор темы katim
  • Дата начала Дата начала
Измените немного формат результата:
Код:
[% FOREACH text IN texts;
    texts.${loop.index}.text.length > 1000 ? texts.${loop.index}.text _ "\n" : '';
END %]

Добрый день. Подскажите, пожалуйста. Как я понял, данный формат результата содержит искомые данные на сайте, так как регулярок в пресете я не вижу. Как понять, что это за переменные (text, texts) и за что они отвечают, откуда берутся, что содержат и тд? Мне нужно сделать похожий парсинг, только парсить не статьи, а конкретные данные. Как я могу их задать?
 
Добрый день. Подскажите, пожалуйста. Как я понял, данный формат результата содержит искомые данные на сайте, так как регулярок в пресете я не вижу. Как понять, что это за переменные (text, texts) и за что они отвечают, откуда берутся, что содержат и тд? Мне нужно сделать похожий парсинг, только парсить не статьи, а конкретные данные. Как я могу их задать?
Добрый день
Если навести курсором мыши на название парсера HTML::TextExtractor, то вы увидите все переменные которые содержат результаты и там есть $p1.texts.$i.text, где texts это наименования массива, а text - это имя переменной в которой содержится один текст, а в texts содержится множество text

Далее, если рассматривать конкретно этот формат результата, то тут используется только переменная texts которая содержит множество текстов. Конструкция FOREACH позволяет нам создать логику прохождения по этому множеству и что-то сделать с каждым текстом

Так как это стандартные результаты, то их задать нельзя, только вывести или обработать, например в конструкторе результатов идёт обработка удаления тегов Remove HTML tags но массив(множество) texts просто перезаписывается, хотя можно было бы складывать в новый массив под новым именем, и уже его тогда нужно было бы выводить в формате результата

Чтобы парсить конкретные данные, то проще создать регулярку и сохранять в новые переменные. Вот тут описано это детально с примерами: https://a-parser.com/docs/guides/task-settings/using-regular-expressions
 
Подскажите, что не так делаю. Импорт выполнил, и без изменений добавил задание. Но оно не выполнилось, и вот лог:

Thread #1 21/08 17:50:21 - 21/08 17:51:22 HTML::TextExtractor::0(Complete): https://a-parser.com/
21/08 17:50:21
Parser HTML::TextExtractor::0 parse query https://a-parser.com/
21/08 17:50:21
Use proxy http://5.252.161.48:3128
21/08 17:50:22
GET(1): https://a-parser.com/ - 596 HTTPS(C) proxy error: 400 Bad Request (0 KB)
21/08 17:50:22
Parse response: 3
21/08 17:50:22
Ban proxy 5.252.161.48:3128 for parser HTML::TextExtractor for 300 seconds
21/08 17:50:22
Use proxy socks5://184.178.172.5:15303
21/08 17:51:21
GET(2): https://a-parser.com/ - 200 OK (truncated by max_size) (1054.16 KB)
21/08 17:51:21
Decode from utf-8(meta charset)
21/08 17:51:21
Parse response: 1
21/08 17:51:21
Thread complete work
 
вроде всё верно делаешь. судя по логу - всё выполнилось, но на сайте апарсера нет нужных по размеру статей.
 
Подскажите, что не так делаю. Импорт выполнил, и без изменений добавил задание. Но оно не выполнилось, и вот лог:

Thread #1 21/08 17:50:21 - 21/08 17:51:22 HTML::TextExtractor::0(Complete): https://a-parser.com/
21/08 17:50:21
Parser HTML::TextExtractor::0 parse query https://a-parser.com/
21/08 17:50:21
Use proxy http://5.252.161.48:3128
21/08 17:50:22
GET(1): https://a-parser.com/ - 596 HTTPS(C) proxy error: 400 Bad Request (0 KB)
21/08 17:50:22
Parse response: 3
21/08 17:50:22
Ban proxy 5.252.161.48:3128 for parser HTML::TextExtractor for 300 seconds
21/08 17:50:22
Use proxy socks5://184.178.172.5:15303
21/08 17:51:21
GET(2): https://a-parser.com/ - 200 OK (truncated by max_size) (1054.16 KB)
21/08 17:51:21
Decode from utf-8(meta charset)
21/08 17:51:21
Parse response: 1
21/08 17:51:21
Thread complete work


В формате результата измените значение с 1000 на 100

4scp2_210822163204.png


и запустите еще раз. Будут найдены текстовые блоки > 100 символов. Просто текстовых блоков более 1000 символов на сайте найдено не было.
 
Добрый день
Если список ссылок собран в большое количество файлов, разложеннывх по подпапкам, есть ли способ в одном задании перебрать все эти файлы?
При выборе папки через обычный диалог "Выберите файл" в разделе "Запросы" в текстовое поле сразу подгружаются имена всех файлов в папке. Если их сотни тысяч, то все просто зависает.
 
При выборе папки через обычный диалог "Выберите файл" в разделе "Запросы" в текстовое поле сразу подгружаются имена всех файлов в папке.
Через интерфейс это единственный способ. Можно то же самое сделать через API.
Но, обратите внимание, на каждый файл будет создано отдельное задание.

Если их сотни тысяч, то все просто зависает.
Если подпапок/файлов очень много, то конечно парсеру нужно будет время, чтобы перечитать их все.
 
Через интерфейс это единственный способ. Можно то же самое сделать через API.
Но, обратите внимание, на каждый файл будет создано отдельное задание.


Если подпапок/файлов очень много, то конечно парсеру нужно будет время, чтобы перечитать их все.
Понял, а если я вручную свормирую список всех файлов, можно ли его для HTML::TextExtractor указать списком, как в этом примере https://a-parser.com/resources/338/ ?
 
попробовал пор образцу https://a-parser.com/resources/420/ сделать аналогичный парсер с HTML::ArticleExtractor
Код:
const fs = require('fs');
const readline = require('readline');
class Parser {
    constructor() {
        this.defaultConf = {
            version: '0.1.24',
            results: {
                flat: [
                    ['Content', 'Content'],
                ]
            },
            results_format: '$p1.textContent.collapse',
            ArticleExtractor_preset: 'default'
        };
        this.editableConf = [
            ['ArticleExtractor_preset', ['combobox', 'HTML::ArticleExtractor preset']],
        ];
    }
    *parse(set, results) {
        if (set.lvl === 0) {
            results.SKIP = 1;
            results.success = 1;
            const files = fs.readdirSync(set.query);
            this.logger.put(`Found ${files.length} files`);
            for (let filename of files) {
                this.query.add({ query: `${set.query}/${filename}`, filename });
            }
        }
        else {
            try {
                var fileStream = fs.createReadStream(set.filename);
                var lineReader = readline.createInterface({
                                      input: fileStream,
                                      crlfDelay: Infinity
                                 });
                this.logger.put(`Current file  ${set.filename} `);
              
                lineReader.on('curr_url', function (curr_url) {
                    this.logger.put(`Current URL ${curr_url}`);
                    let resp = yield this.parser.request('HTML::ArticleExtractor', this.conf.ArticleExtractor_preset, {}, curr_url);
                    if(resp.info.success) results.Content = resp.textContent.collapse;
                    results.success = resp.info.success;                  
                });
            }
          
            catch(e) {
                this.logger.put(`Error: ${e.message}`);
                results.success = 0;
            }
        }
        return results;
    }
}
но получаю ошибку
Error: Start: JS::FilesFromDirText Error: files/parsers/FilesFromDirText/FilesFromDirText.js:45 let resp = yield this.parser.request('HTML::ArticleExtractor', this.conf.ArticleExtractor_preset, {}, curr_url); ^^^^^ SyntaxError: Unexpected strict mode reserved word at new Script (node:vm:99:7) at createScript (node:vm:260:10) at Object.runInContext (node:vm:291:10) at evalmachine.:1:16930 at __requireParserAsModule (evalmachine.:1:11521) at __prepareParserClass (evalmachine.:1:11941) at unknown:1:1 at Script.runInContext (node:vm:141:12) at Object.runInContext (node:vm:292:6) at evalmachine.:1:16930 at build/core.to_build.pl line 63587.

я упустил что-то важное?
 
но получаю ошибку
Нужно использовать async генератор и читать строки используя await. А также, лучше немного изменить логику работы, добавив еще один уровень запросов:
0) Читаем список файлов из каталога
1) Читаем список ссылок из каждого файла
2) Парсим данные по каждой ссылке

Вот рабочее решение:
Код:
const fs = require('fs');
const readline = require('readline');
class Parser {
    constructor() {
        this.defaultConf = {
            results: {
                flat: [
                    ['Content', 'Content']
                ]
            },
            results_format: '[% Content.collapse %]',
            HTML_ArticleExtractor_preset: 'default'
        };
        this.editableConf = [
            ['HTML_ArticleExtractor_preset', ['combobox', 'HTML::ArticleExtractor preset']]
        ];
    }

    async *parse(set, results) {
        if(set.lvl == 0) {
            this.logger.put(`Read directory ${set.query}`);
            const files = fs.readdirSync(set.query);
            for (let filename of files) {
                this.query.add(`${set.query}\\${filename}`);
            }
            this.logger.put(`Found ${files.length} files`);
            results.SKIP = 1;
            results.success = 1;
        } else if(set.lvl == 1) {
            try {
                this.logger.put(`Read file ${set.query}`);
                let fileStream = fs.createReadStream(set.query);
                let lineReader = readline.createInterface({
                                      input: fileStream,
                                      crlfDelay: Infinity
                                 });
                let count = 0;
                for await (const url of lineReader) {
                    this.query.add(url);
                    count++;
                }
                this.logger.put(`Found ${count} urls`);
                results.success = 1;
            } catch(e) {
                this.logger.put(`Error: ${e.message}`);
                results.success = 0;
            }
            results.SKIP = 1;
        } else {
            let resp = yield this.parser.request('HTML::ArticleExtractor', this.conf.HTML_ArticleExtractor_preset, {}, set.query);
            results.success = resp.info.success;
            if(resp.info.success) results.Content = resp.textContent;
        }

        return results;
    }
}
 
Назад
Верх