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

JavaScript парсеры: расширенный функционал A-Parser

Тема в разделе "Техническая поддержка по JavaScript парсерам", создана пользователем Forbidden, 11 дек 2016.

  1. seowin555

    seowin555 A-Parser Pro License
    A-Parser Pro

    Регистрация:
    29 сен 2016
    Сообщения:
    187
    Симпатии:
    37
    решил проблему, нектуально...
     
    #21 seowin555, 6 мар 2017
    Последнее редактирование: 6 мар 2017
  2. Forbidden

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

    Регистрация:
    9 мар 2013
    Сообщения:
    3.337
    Симпатии:
    1.794
    С версии 1.1.772 добавлено автоматическое версионирование при сохранении кода парсера через встроенный редактор:
    Код:
            this.defaultConf = {
                version: '0.1.1',
    
    • Версия имеет формат: Major.Minor.Revision
    • Значение Revision(последняя цифра) автоматически увеличивается при каждом сохранении
    • Остальные значения(Major, Minor) можно менять вручную, а также сбрасывать Revision в 0 для
    • Если по каким то причинам необходимо менять Revision только вручную, то версию необходимо заключить в двойные кавычки ""
     
    evova, relay и Support нравится это.
  3. Forbidden

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

    Регистрация:
    9 мар 2013
    Сообщения:
    3.337
    Симпатии:
    1.794
    С версии 1.1.774 добавлен функционал по работе с каптчей:
    • yield this.captcha.recognize(preset, image, type, overrides) - загрузка каптчи для распознавания, image - бинарные данные картинки для распознавания, preset указывает на пресет для 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) - сообщить сервису что каптча разгадана неверно
    Небольшой пример по использованию:
    Код:
        *parse(set, results) {
            set.query = 'https://a-parser.com/img/captcha.jpeg'
          
            //Manual download captcha + recognize + report bad
            let response = yield this.request('GET', set.query, {}, {});
    
            if(response.success) {
                const captcha = yield this.captcha.recognize('antigate.com', response.data, 'jpeg');
                if(captcha.answer) {
                    this.logger.put('Captcha Answer: ' + captcha.answer);
                    if(captcha.answer != 'ifignt eyelids') {
                        yield this.captcha.reportBad('antigate.com', captcha.id);
                    }
                }
                else {
                    this.logger.put('Captcha recognize error: ' + captcha.error);
                }
                this.logger.put('Recognize from data: ' + JSON.stringify(captcha));
            }
          
            //Auto download captcha
            const captcha = yield this.captcha.recognizeFromUrl('antigate.com', set.query);
          
            this.logger.put('Recognize from url: ' + JSON.stringify(captcha));
          
            results.success = 1;
    
            return results;
        }
    
     
    evova и Support нравится это.
  4. Support

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

    Регистрация:
    16 мар 2012
    Сообщения:
    4.544
    Симпатии:
    2.163
    • Обновлен пример парсинга Mail.Ru с возможностью использовать антигейт через yield this.captcha.*
     
    #24 Support, 14 мар 2017
    Последнее редактирование: 14 мар 2017
    relay и Forbidden нравится это.
  5. ro--ot

    ro--ot A-Parser Enterprise License
    A-Parser Enterprise

    Регистрация:
    19 май 2016
    Сообщения:
    38
    Симпатии:
    42
    Очень хотелось бы увидеть полный аналог парсера Net::HTTP на JavaScript с поддержкой антигейта.
     
    btr нравится это.
  6. btr

    btr A-Parser Enterprise License
    A-Parser Enterprise

    Регистрация:
    11 фев 2013
    Сообщения:
    198
    Симпатии:
    116
    Если можно то на примере поисковика Rambler.
     
  7. Forbidden

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

    Регистрация:
    9 мар 2013
    Сообщения:
    3.337
    Симпатии:
    1.794
    this.request это и есть аналог этого парсера, поддержка каптчи уже реализована же :)
     
  8. ro--ot

    ro--ot A-Parser Enterprise License
    A-Parser Enterprise

    Регистрация:
    19 май 2016
    Сообщения:
    38
    Симпатии:
    42
    А можно оформить так же как парсер Mail.ru? :)
     
    Force68, btr и vipuncle нравится это.
  9. Newsoros

    Newsoros A-Parser Enterprise License
    A-Parser Enterprise

    Регистрация:
    16 мар 2017
    Сообщения:
    13
    Симпатии:
    1
    Добрый день. Можно ли 5 пример "Парсинг текстовки по ключу" HTML::TextExtractor заменить на NET::HTTP? Попытался по аналоги переписать, но не вышло:
    class Parser {
    constructor() {
    this.defaultConf = {
    results: {
    flat: [
    ['key', 'Keyword'],
    ['link', 'Link'],
    ['data', 'Data'],
    ]
    },
    results_format: "$key - $link\\n$data\\n\\n",
    search_engine: 'SE::Google',
    SE_Google_preset: 'default',
    SE_Yandex_preset: 'default',
    NET_HTTP_preset: 'default',
    };
    this.editableConf = [
    ['SE_Google_preset', ['combobox', 'SE::Google preset']],
    ['SE_Yandex_preset', ['combobox', 'SE::Yandex preset']],
    ['NET_HTTP_preset', ['combobox', 'NET::HTTP preset']],
    ['search_engine', ['combobox', 'Search engine', ['SE::Google', 'Google'], ['SE::Yandex', 'Yandex']]],
    ];
    }

    *parse(set, results) {
    return yield* set.lvl == 0 ? this.parseSE(set, results) : this.parseText(set, results);
    }

    *parseSE(set, results) {
    this.logger.put("Start scraping query: " + set.query);

    this.logger.put(`Use ${this.conf.search_engine}`);
    let SEresp = yield this.parser.request(
    this.conf.search_engine,
    this.conf[this.conf.search_engine.replace(/::/, '_') + '_preset'],
    set.query
    );

    if(SEresp.info.success) {
    let link_count = 0;
    let step = this.conf.search_engine == 'SE::Google' ? 3 : 5;
    for (let i = 0; i < SEresp.serp.length; i += step) {
    const link = SEresp.serp;
    this.query.add(link);
    link_count += 1;
    }
    this.logger.put("Added " + link_count + " links");
    results.success = 1;
    results.SKIP = 1;
    return results;
    }
    else {
    this.logger.put(`Error scraping ${this.conf.search_engine}`);
    results.success = 0;
    return results;
    }
    }

    *parseText(set, results) {
    this.logger.put("Scraping text from " + set.query);
    let response = yield this.parser.request('NET::HTTP', this.conf.NET_HTTP_preset, set.query);
    results.key = set.first;
    results.link = set.query;
    if(response.info.success) {
    results.data = response.data;//????????
    this.logger.put(set.query + " - " + response.data.length + " blocks, " + results.data.length + " chars");
    results.success = 1;
    }
    else {
    this.logger.put(set.query + " - error scraping text");
    results.success = 0;
    }
    return results;
    }
    }
     
  10. Support

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

    Регистрация:
    16 мар 2012
    Сообщения:
    4.544
    Симпатии:
    2.163
    Добрый день.
    Легко. Достаточно заменить HTML::TextExtractor на Net::HTTP и выводить не объединенные блоки текста, а просто data.
    Код:
    class Parser {
        constructor() {
            this.defaultConf = {
                version: '0.1.1',
                results: {
                    flat: [
                        ['key', 'Keyword'],
                        ['link', 'Link'],
                        ['content', 'Page content'],
                    ]
                },
                results_format: "$key - $link\\n$content\n\\n",
                search_engine: 'SE::Google',
                SE_Google_preset: 'default',
                SE_Yandex_preset: 'default',
                Net_HTTP_preset: 'default',
            };
            this.editableConf = [
                ['SE_Google_preset', ['combobox', 'SE::Google preset']],
                ['SE_Yandex_preset', ['combobox', 'SE::Yandex preset']],
                ['Net_HTTP_preset_preset', ['combobox', 'Net::HTTP preset']],
                ['search_engine', ['combobox', 'Search engine', ['SE::Google', 'Google'], ['SE::Yandex', 'Yandex']]],
            ];
        }
    
           
        *parse(set, results) {
            return yield* set.lvl == 0 ? this.parseSE(set, results) : this.parseContent(set, results);
        }
       
        *parseSE(set, results) {
            this.logger.put("Start scraping query: " + set.query);
    
            this.logger.put(`Use ${this.conf.search_engine}`);
            let SEresp = yield this.parser.request(
                this.conf.search_engine,
                this.conf[this.conf.search_engine.replace(/::/, '_') + '_preset'],
                set.query
            );
    
            if(SEresp.info.success) {
                let link_count = 0;
                let step = this.conf.search_engine == 'SE::Google' ? 3 : 5;
                for (let i = 0; i < SEresp.serp.length; i += step) {
                    const link = SEresp.serp[i];
                    this.query.add(link);
                    link_count += 1;
                }
                this.logger.put("Added " + link_count + " links");
                results.success = 1;
                results.SKIP = 1;
                return results;
            }
            else {
                this.logger.put(`Error scraping ${this.conf.search_engine}`);
                results.success = 0;
                return results;
            }
        }
    
        *parseContent(set, results) {
            this.logger.put("Scraping content from " + set.query);
            let response = yield this.parser.request('Net::HTTP', this.conf.Net_HTTP_preset, set.query);
            results.key = set.first;
            results.link = set.query;
            if(response.info.success) {
                results.content = response.data;
                results.success = 1;
            }
            else {
                this.logger.put(set.query + " - error scraping content");
                results.success = 0;
            }
            return results;
        }
    }
    
     
    Forbidden и relay нравится это.
  11. Forbidden

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

    Регистрация:
    9 мар 2013
    Сообщения:
    3.337
    Симпатии:
    1.794
    С версии 1.1.805 добавлен метод this.util.updateResultsData(results, data) для автоматического заполнения ($pages.$i.data и $data), необходимо вызывать для добавления контента результирующей страницы
     
    #31 Forbidden, 4 апр 2017
    Последнее редактирование: 4 апр 2017
  12. Forbidden

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

    Регистрация:
    9 мар 2013
    Сообщения:
    3.337
    Симпатии:
    1.794
    С версии 1.1.807 добавлен метод this.util.urlFromHTML(url, [base]), обрабатывает ссылку полученную из HTML кода - декодирует entities(&amp; и т.п.), опционально можно перед base - базовый урл(например урл исходной страницы), таким образом может быть получена полная ссылка
     
  13. webdev

    webdev New Member

    Регистрация:
    26 сен 2017
    Сообщения:
    21
    Симпатии:
    4
    ДД. Подскажите, где прочитать как работает встроенный обработчик попыток? Что такое успешная и не успешная попытка?
     
  14. Kreola

    Kreola Member

    Регистрация:
    23 июн 2013
    Сообщения:
    203
    Симпатии:
    19
    Приветствую
    Если я правильно понимаю, то успешная попытка, это попытка когда все запросы вернули положительное значение. т.е. берем 10 листов гугла, если парсер проходит по ним всем и получает данные, то это считается положительной попыткой. Если же парсер прошел ни одной либо прошел < 10, в данном случае, то это неуспешная попытка, хотя результат выведется.
    Хотя могу и ошибаться.
     
  15. webdev

    webdev New Member

    Регистрация:
    26 сен 2017
    Сообщения:
    21
    Симпатии:
    4
    Немного уточню.
    В настройках парсера стоит Кол-во попыток: 1000.

    Вариант 1.
    Если я выполняю этот запрос, то он будет выполняться пока не получу код ответа 200 и не пройдет валидация контента согласно регулярке в check_content и так до 1000 раз?
    При не успешной попытке прокси-сервер меняется?

    Код:
    let response = yield this.request('GET', 'https://foobar/', {}, {
        check_content: ['<\/html>'],
        decode: 'auto-html',
        parsecodes: {200: 1},
        browser: 1,
    });
    
    Вариант 2.
    Я вручную управляю счетчиком попыток скачки с помощью параметра attempt.
    В этом случае успешность запроса определяется так же, как в 1-м варианте?
    Прокси-сервер я здесь меняю сам.

    Код:
    for(attempt = 1; attempt <= this.conf.proxyretries; attempt++) {
        let response = yield this.request('GET', 'https://foobar/', {}, {
            check_content: ['<\/html>'],
            decode: 'auto-html',
            parsecodes: {200: 1},
            browser: 1,
            attempt: attempt,
        });
        if (response.success) {
            break;
        }
        this.proxy.next();
    }
    
     
  16. Support Денис

    Support Денис A-Parser Enterprise License
    A-Parser Enterprise

    Регистрация:
    12 июн 2017
    Сообщения:
    586
    Симпатии:
    185
    Здравствуйте.
    1) В первом варианте будет перебирать прокси, пока код ответа не будет 200 и и код страницы не будет соответствовать регулярке в check_content ,либо пока не закончится число попыток. Прокси будут меняться при этоем, если конечно парсите с прокси.
    2) В описанном вами 2 варианте успешность запроса определяется так же как и в 1-ом варианте.
     
  17. webdev

    webdev New Member

    Регистрация:
    26 сен 2017
    Сообщения:
    21
    Симпатии:
    4
    Kreola, Support Денис, спасибо!
     
    Support Денис нравится это.
  18. ernet

    ernet A-Parser Pro License
    A-Parser Pro

    Регистрация:
    2 окт 2013
    Сообщения:
    21
    Симпатии:
    0
    Скажите, javaScript парсер обрабатывает js скриаты на странице доноре?
    У меня такая задача, весть контент на странице выводится через js скрипт, как спарсить с такой страницы?
     
  19. Support Денис

    Support Денис A-Parser Enterprise License
    A-Parser Enterprise

    Регистрация:
    12 июн 2017
    Сообщения:
    586
    Симпатии:
    185
    Здравствуйте.
    Если контент страницы собирается динамически js скриптом, то нужно использовать инструменты разработчика в браузере и смотреть какие запросы и с какими данными отправляются.
    Например на сайте olx.ua чтобы увидеть телефон продавца надо нажать на кнопку и тогда открывается телефон. Открываем инструменты разработчика, смотрим какой запрос добавился при нажатии смотрим его ответ , и если это то что нужно, то отправляем запрос с такими заголовками и переменными.
    [​IMG]
     
  20. ernet

    ernet A-Parser Pro License
    A-Parser Pro

    Регистрация:
    2 окт 2013
    Сообщения:
    21
    Симпатии:
    0
    Вся страница выводится неск скриптами
    Если смотреть через браузер, то видна норм страница, если через гет пост, то видны только скрипты.
     

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