Мне нужна помощь, чтобы изменить сканер Apify - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть сканер Apify, который работает и получает все нужные мне данные, но сканер не ожидает полной загрузки страницы, и поэтому я получаю неполный набор результатов. Вот этот код:

  function pageFunction(context) {
    var $ = context.jQuery;
    var results = [];
    $(".card-product-a").each(function() {
        results.push({
         Product_Name: $(this).find(".card-product-a__name").text().trim(),
         Packaging: $(this).find(".card-product-a__packaging").text().trim(),
         Price_Integer: $(this).find(".product-price__integer").text().trim(),
         Price_Decimal: $(this).find(".product-price__decimal").text().trim(),
         Unit_Price: $(this).find(".product-price__unit").text().trim(),
         Unit_Price_summary: $(this).find(".product- 
   price__summary").text().trim(),
         Image_Url: $(this).find(".card-product- 
   a__media.clic_open_product_fiche").attr('data-lazyload-src')
       });
    });
    return results;
    }

А вот копия страницы и первая строка, которую я хочу сканировать:

<div class="product-list">
    <!-- Grille de produits -->
    <ul class="product-list__content product-grid-b" data-target="product-list">

    <li data-product-id="2910" data-promo="1" data-vll="1" data-alcool-warning="0" class="product-grid-b__item  product product_2910">

        <div class="card-product-a">
            <div class="card-product-a__sticker sticker sticker--special"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">The 2nd at -70%</font></font></div>            <div class="card-product-a__panel">
                <!-- fiche -->
                <div class="card-product-a__media clic_open_product_fiche " data-visibility="visible" data-lazyload="" data-lazyload-state="loaded" data-lazyload-src="/datas/images/152254/150/200/2910.jpg?v2.1.463" style="background-image: url(&quot;/datas/images/152254/150/200/2910.jpg?v2.1.463&quot;);"></div>
                <div class="card-product-a__name clic_open_product_fiche"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Soybean drink calcium source, Bio</font></font></div>
                <div class="card-product-a__packaging"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">1 L</font></font></div>
                <div class="card-product-a__mention"></div>

                <!-- footer -->
                <div class="card-product-a__row">

                    <!-- prix -->
                    <div class="card-product-a__col">
                        <div class="card-product-a__price">

                            <div class="product-price">

                                <div class="product-price__group">

                                    <div class="product-price__number  ">
                                        <span class="product-price__integer"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">1 </font></font></span>
                                        <span class="product-price__decimal"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">19</font></font></span>
                                    </div>

                                                                    </div>

                                                                    <div class="product-price__unit"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">€ / Piece</font></font></div>
                                    <div class="product-price__summary"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">That's 1.19 € / LITER</font></font></div>
                                                            </div>
                        </div>
                    </div>

                    <!-- promo + favori -->
                    <div class="card-product-a__col">

                        <div class="card-product-a__offer">
                                                            <a onclick="addProductByPromo(2910, 2, $(this))"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">Buy the promo</font></font></a>
                                                    </div>


                                            </div>

                                            <!-- quantité -->
                        <div class="card-product-a__col">
                            <div class="card-product-a__quantity product-quantity" product-quantity="2910">
                                <div class="product-quantity__more" data-trigger="up" aria-hidden="true" aria-label="Augmenter la quantité"></div>
                                <div class="product-quantity__count" data-target="count"><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">0</font></font></div>
                                <div class="product-quantity__less" data-trigger="down" aria-hidden="true" aria-label="Diminuer la quantité"></div>
                            </div>
                        </div>
                                    </div>

            </div>
    </div></li>

<script>
    if(!adblock){
        $('#bloc_encart_1').show();
        googletag.cmd.push(function() {
            googletag.display('div-gpt-ad-1499076737480-0');

            // met a jour l'id du rayon avant de refresh les pub
            googletag.pubads().setTargeting('Rayon', [2]);
            googletag.pubads().refresh();
        });

    }
</script>

В их документации здесь: https://www.apify.com/docs/crawler#waiting-for-dynamic-content вы можете использовать pageFunction для ожидания загрузки динамического содержимого, используя следующий код:

function pageFunction(context) {
var $ = context.jQuery;
var startedAt = Date.now();

var extractData = function() {
    // timeout after 10 seconds
    if( Date.now() - startedAt > 10000 ) {
        context.finish("Timed out before #my_element was loaded");
        return;
    }

    // if my element still hasn't been loaded, wait a little more
    if( $('#my_element').length === 0 ) {
        setTimeout(extractData, 500);
        return;
    }

    // refresh page screenshot and HTML for debugging
    context.saveSnapshot();

    // save a result
    context.finish({
        value: $('#my_element').text()
    });
};

// tell the crawler that pageFunction will finish asynchronously
context.willFinishLater();

extractData();
}

Проблема, с которой я столкнулся, заключается в том, что мне кажется, что я не могу объединить их для получения необходимых мне данных.

Я пробовал это без радости:

function pageFunction(context) {
var $ = context.jQuery;
var startedAt = Date.now();

var extractData = function() {
    // timeout after 10 seconds
    if( Date.now() - startedAt > 10000 ) {
        context.finish(".card-product-a");
        return;
    }

    // if my element still hasn't been loaded, wait a little more
    if( $('.card-product-a').length === 0 ) {
        setTimeout(extractData, 500);
        return;
    }

    // refresh page screenshot and HTML for debugging
    context.saveSnapshot();

    // save a result
    context.finish({
         Product_Name: $(this).find(".card-product-a__name").text().trim(),
         Packaging: $(this).find(".card-product-a__packaging").text().trim(),
         Price_Integer: $(this).find(".product-price__integer").text().trim(),
         Price_Decimal: $(this).find(".product-price__decimal").text().trim(),
         Unit_Price: $(this).find(".product-price__unit").text().trim(),
         Unit_Price_summary: $(this).find(".product-price__summary").text().trim(),
         Image_Url: $(this).find(".card-product-a__media.clic_open_product_fiche").attr('data-lazyload-src')
    });
};

// tell the crawler that pageFunction will finish asynchronously
context.willFinishLater();

extractData();
}

Любая помощь будет принята с благодарностью.

Спасибо

1 Ответ

0 голосов
/ 07 ноября 2018

Я обнаружил ответ. Вот, если кому-то нужно.

function pageFunction(context) {
    var $ = context.jQuery;
    var startedAt = Date.now();

    var extractData = function() {
        // timeout after 10 seconds
        if( Date.now() - startedAt > 10000 ) {
            context.finish("Timed out before #my_element was loaded");
            return;
        }

        // if my element still hasn't been loaded, wait a little more
        if( $('.card-product-a').length === 0 ) {
            setTimeout(extractData, 500);
            return;
        }

        // refresh page screenshot and HTML for debugging
        context.saveSnapshot();

        // save a result
        var result = [];
        $('.card-product-a').each(function(){
            result.push({
             Product_Name: $(this).find(".card-product-a__name").text().trim(),
             Packaging: $(this).find(".card-product-a__packaging").text().trim(),
             Price_Integer: $(this).find(".product-price__integer").text().trim(),
             Price_Decimal: $(this).find(".product-price__decimal").text().trim(),
             Unit_Price: $(this).find(".product-price__unit").text().trim(),
             Unit_Price_summary: $(this).find(".product-price__summary").text().trim(),
             Image_Url: $(this).find(".card-product-a__media.clic_open_product_fiche").attr('data-lazyload-src')
            });    
        });
        context.finish(result);
    };

    // tell the crawler that pageFunction will finish asynchronously
    context.willFinishLater();

    extractData();
}
...