1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вступайте в наш Telegram чат: https://t.me/a_parser Нас уже 2600+ и мы растем!
    Скрыть объявление

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

Парсинг статей с заданного списка сайтов

  1. Serge #

    Serge # New Member

    Регистрация:
    7 июл 2021
    Сообщения:
    1
    Симпатии:
    0
    Добрый день. Подскажите, пожалуйста. Как я понял, данный формат результата содержит искомые данные на сайте, так как регулярок в пресете я не вижу. Как понять, что это за переменные (text, texts) и за что они отвечают, откуда берутся, что содержат и тд? Мне нужно сделать похожий парсинг, только парсить не статьи, а конкретные данные. Как я могу их задать?
     
  2. Support Ilia

    Support Ilia Moderator
    Команда форума A-Parser Enterprise

    Регистрация:
    6 апр 2020
    Сообщения:
    370
    Симпатии:
    65
    Добрый день
    Если навести курсором мыши на название парсера 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
     
  3. Сергей 222

    Сергей 222 A-Parser Pro License
    A-Parser Pro

    Регистрация:
    25 окт 2018
    Сообщения:
    27
    Симпатии:
    1
    Подскажите, что не так делаю. Импорт выполнил, и без изменений добавил задание. Но оно не выполнилось, и вот лог:

    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
     
  4. DeLaKroiX

    DeLaKroiX A-Parser Enterprise License
    A-Parser Enterprise

    Регистрация:
    25 дек 2015
    Сообщения:
    267
    Симпатии:
    96
    вроде всё верно делаешь. судя по логу - всё выполнилось, но на сайте апарсера нет нужных по размеру статей.
     
  5. Support Alex

    Support Alex Moderator
    Команда форума A-Parser Enterprise

    Регистрация:
    1 окт 2019
    Сообщения:
    279
    Симпатии:
    50

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

    [​IMG]

    и запустите еще раз. Будут найдены текстовые блоки > 100 символов. Просто текстовых блоков более 1000 символов на сайте найдено не было.
     
  6. Oleter

    Oleter A-Parser Pro License
    A-Parser Pro

    Регистрация:
    23 июл 2021
    Сообщения:
    6
    Симпатии:
    0
    Добрый день
    Если список ссылок собран в большое количество файлов, разложеннывх по подпапкам, есть ли способ в одном задании перебрать все эти файлы?
    При выборе папки через обычный диалог "Выберите файл" в разделе "Запросы" в текстовое поле сразу подгружаются имена всех файлов в папке. Если их сотни тысяч, то все просто зависает.
     
  7. Support

    Support Administrator
    Команда форума A-Parser Enterprise

    Регистрация:
    16 мар 2012
    Сообщения:
    4.389
    Симпатии:
    2.112
    Через интерфейс это единственный способ. Можно то же самое сделать через API.
    Но, обратите внимание, на каждый файл будет создано отдельное задание.

    Если подпапок/файлов очень много, то конечно парсеру нужно будет время, чтобы перечитать их все.
     
  8. Oleter

    Oleter A-Parser Pro License
    A-Parser Pro

    Регистрация:
    23 июл 2021
    Сообщения:
    6
    Симпатии:
    0
    Понял, а если я вручную свормирую список всех файлов, можно ли его для HTML::TextExtractor указать списком, как в этом примере https://a-parser.com/resources/338/ ?
     
  9. Support

    Support Administrator
    Команда форума A-Parser Enterprise

    Регистрация:
    16 мар 2012
    Сообщения:
    4.389
    Симпатии:
    2.112
    Можно только если написать аналогичную обертку для HTML::TextExtractor реализующую чтение файлов по путям, указанным в поле запросов.
     
  10. Oleter

    Oleter A-Parser Pro License
    A-Parser Pro

    Регистрация:
    23 июл 2021
    Сообщения:
    6
    Симпатии:
    0
    попробовал пор образцу 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.

    я упустил что-то важное?
     
  11. Support

    Support Administrator
    Команда форума A-Parser Enterprise

    Регистрация:
    16 мар 2012
    Сообщения:
    4.389
    Симпатии:
    2.112
    Нужно использовать 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;
        }
    }
     
    Oleter нравится это.

Поделиться этой страницей