Создание JS парсеров. Парсинг title и description для топ10 сайтов по запросу.

Парсим топ10 и содержимое тегов title и description для этих сайтов

Метки:
  1. Support Денис
    В этой статье мы продолжим изучать создание JS парсеров на основе A-Parser.

    В данном парсере мы сделаем возможность выбирать по какому поисковику собирать топ 10. Выбирать будем из Google, Yandex или Bing. Также предоставим возможность выбрать пресет для парсера поисковой системы.

    Задачу будем решать в несколько действий. Первым нашим шагом будет описание дефолтных и редактируемых настроек, далее мы с вами опишем метод который по ссылке будет получать содержимое тегов title и description. Следующим шагом будет получение ссылок из выдачи с помощью одного из внутренних парсеров и наконец в финальным действием будет перебор полученных ссылок и вызов метода для получения содержимого тегов на каждом витке цикла.

    Наши настройки будут выглядеть так
    Код:
    class Parser {
        constructor() {
            this.defaultConf = {
                results: {
                    arrays :{
                        /*В результате будет хеш serp в котором будут переменные
                         domain, title и description*/
                        serp :['Top 10 domains and title',[
                            ['domain', 'domain name'],
                            ['title','the contents of the title tag'],
                            ['description', 'the contents ot the description tag'],
                        ]],
                    }
                },
                /*Формат результата*/
                results_format: "$serp.format('$domain - $title - $description\\n')",
                /*Код ответа*/
                parsecodes: {
                    200: 1,
                },
                /*Максимальный размер ответа*/
                max_size: 200 * 1024,
                search_engine: 'SE::Google::Modern',//Парсер поисковика по умолчанию.
                SE_Google_Modern_preset: 'default',//Пресеты для парсеров по умолчанию
                SE_Yandex_preset: 'default',
                SE_Bing_preset: 'default',
            };
             this.editableConf = [
             ['SE_Google_Modern_preset', ['combobox', 'SE::Google::Modern preset']],
             ['SE_Yandex_preset', ['combobox', 'SE::Yandex preset']],
             ['SE_Bing_preset', ['combobox', 'SE::Bing preset']],
             ['search_engine', ['combobox', 'Search engine',
                        ['SE::Google::Modern', 'Google'],
                        ['SE::Yandex', 'Yandex'],
                        ['SE::Bing','Bing'],
                        ]],
            ];
        }
    
    Теперь давайте опишем метод который будем принимать в качестве параметра ссылку, а возвращать хеш c содержанием тега title и meta тега description если они есть.
    В данном методе мы будем отправлять обычный запрос используя this.request.
    Код:
    /*Метод принимающий на вход ссылку на страницу и возвращающий хеш с содержанием title и descritpion*/
        *parseTitleDescription(link){
            let titleDescr = {};
            let response = yield this.request('GET',link,{},{
                decode: 'auto-html',
            });
            if(response.success){
                let title = response.data.match(/<title>([\s\S]+?)<\/title>/);
                if(title)
                    titleDescr["title"] = title[1];
                let description = response.data.match(/meta.+?=".*?description"\s+content="(.*?)"/);
                if(description)
                    titleDescr["descr"] = description[1];
            }
            return titleDescr;
        }
    Теперь когда метод для сбора title и description готов, перейдем к описанию метода parse.
    В отличие от вышеописанного метода, здесь мы будем использовать this.parser.request так как нам надо отправить не обычный запрос, а парсить с помощью одного из внутренних парсеров.
    Код:
    *parse(set, results) {
               let response = yield this.parser.request(
                this.conf.search_engine, //Парсить будем выбранным парсером.
                this.conf[this.conf.search_engine.replace(/::/g, '_') + '_preset'],{ //Указываем пресет
                     pagecount: 1,//задаем через override одну страницу
                     linksperpage: 10,//задаем через override 10 результатов на страницу
                },set.query);
            if(response.info.success) {
                let step;
                /*Устанавливаем шаг прохода по циклу в зависимости от парсера.
                Для SE::Google::Modern и SE::Bing 3, а для SE::Yandex 6*/
                if(this.conf.search_engine == 'SE::Google::Modern' || this.conf.search_engine == 'SE::Bing' ){
                    step = 3;
                }
                else{
                    step = 6;
                }
                for(let i = 0 ; i < response.serp.length ; i+= step){
                    /*Для каждой ссылки вызываем метод parseTitleDescription*/
                    let tDescr = yield* this.parseTitleDescription(response.serp[i]);
                    /*Записываем в массив результатов. С помощью this.utils.url.extractDomain достаем из ссылки только домен*/
                    results.serp.push(this.utils.url.extractDomain(response.serp[i]),tDescr["title"],tDescr["descr"]);
                }
            }
            results.success = response.success;
            return results;
        }
    
    Сам пресет вы можете скачать по этой ссылке