【问题标题】:Store multiple scraping data in an Array将多个抓取数据存储在一个数组中
【发布时间】:2016-08-18 13:10:29
【问题描述】:

第一部分:

目前我抓取网页以获取链接,然后我打开每个抓取的链接,这部分工作完美。

第二部分:

我检查是否有一个(选择)选项字段的选择并将值(id)存储在一个数组中,这部分也可以正常工作。

第三部分:

我想遍历它们(选择选项)并触发点击事件并等待 AJAX 响应然后提取 infoProduct 然后将其存储在一个数组中。

我在这部分遇到了麻烦,我得到了一个空数组,因为在第一个 this.eachThen 开始之前调用了 return listProducts

function getInfosProduct(obj,variation) {
    if (!variation) {
        return [{
            name: getName(),
            image: products.image.getElement.link + getImage(),
            url: obj.url
        }];
    } else {
        return {
            name: getName(),
            image: products.image.getElement.link + getImage(),
            url: variation.url,
            idVariation: variation.id,
            descVariation: variation.description
        };
    }
}

function clickVariation(variation) {
    if (variation.ok && variation.id != variation.ignore) {
        chooseVariation(products.selector, variation.id);
        return true;
    }
    return false;
}

casper.getInfosProducts = function(obj) {
    if (obj.level == 0) {
        return this.evaluate(getInfosProduct, obj,false);
    } else {
        listProducts = [];
        this.eachThen(obj.levelVariation, function getInfosProducts(variation) {
            isClick = this.evaluate(clickVariation, variation.data)
            if (isClick) {

                this.waitForSelectorTextChange('.selector', function() {
                    this.echo('The text on .selector has been changed.');
                });

                listProducts.push(this.evaluate(getInfosProduct, obj,variation.data));
                                }
        });
        return listProducts;
    }
};

在选择元素上触发更改事件的函数

function chooseVariation(selector, valueToMatch) {
    var select = document.querySelectorAll(selector),
        found = false;
    Array.prototype.forEach.call(select, function(opt, i) {
        if (!found && opt.value.indexOf(valueToMatch) !== -1) {
            select.selectedIndex = i;
            found = true;
        }
    });
    // dispatch change event in case there is some kind of validation
    var evt = document.createEvent("UIEvents"); // or "HTMLEvents"
    evt.initUIEvent("change", true, true);
    select[0].dispatchEvent(evt);
}

这是主要功能:

    function startSraping(obj) {
        casper.then(function switchAction() {
            switch (obj.action) {

                //......... some code ........

          // iterating through array links and open pages
            case "openLinks":
                this.each(links, function eachOpenLinks(self, link) {
                    if (link.ok) {
                        self.thenOpen(link.url, function thenOpenLinks() {
                            startSraping({
                                url: link.url,
                                action: "getVariations"
                            });
                        });
                    } 
                });
                break;

                    // get all variations for each page opend
                case "getVariations":
                    objVariations = this.getVariations(obj.url);
                    startSraping({
                        url: obj.url,
                        action: "getInfosProducts",
                        objVariations: objVariations
                    });
                    break;

                case "getInfosProducts":
                    this.eachThen(obj.objVariations.list, function(levelVariation) {
                        infosProd = this.getInfosProducts({
                            levelVariation: levelVariation.data,
                            url: obj.url,
                            level: obj.objVariations.level
                        });
                      // Here I got an empty array
                        this.echo(JSON.stringify(infosProd), 'INFO');
                    });
                    break;
            }
        });
    }
    casper.start(url, function start() {
        startSraping({
            variation: variation,
            action: "submitSearch"
        });
    });
    casper.run();

【问题讨论】:

    标签: javascript casperjs


    【解决方案1】:

    您不能在应该以同步方式 (general reference) 从异步函数返回结果的函数内部调用异步函数(eachThenwaitForSelectorTextChange 都是异步的)。由于 CasperJS 不支持 Promises,因此这有点棘手。

    我认为以下更改应该是最小的,可以让你到达你想去的地方。

    casper.getInfosProducts = function(obj, callback) {
        if (obj.level == 0) {
            this.then(function(){
                callback.call(this, arr.push(this.evaluate(getInfosProduct, obj,false));
            });
        } else {
            var listProducts = [];
            this.eachThen(obj.levelVariation, function getInfosProducts(variation) {
                var isClick = this.evaluate(clickVariation, variation.data)
                if (isClick) {
                    this.waitForSelectorTextChange('.selector', function() {
                        this.echo('The text on .selector has been changed.');
                        listProducts.push(this.evaluate(getInfosProduct, obj, variation.data));
                    });
                }
            });
            this.then(function(){
                callback.call(this, listProducts);
            });
        }
    };
    

    startSraping:

    case "getInfosProducts":
        this.eachThen(obj.objVariations.list, function(levelVariation) {
            this.getInfosProducts({
                levelVariation: levelVariation.data,
                url: obj.url,
                level: obj.objVariations.level
            }, function (infosProd){
                // this is the asynchronous callback
                this.echo(JSON.stringify(infosProd), 'INFO');
            });
        });
        break;
    

    【讨论】:

    • 天才回答,“我读了你关于同步/异步的帖子,然后/等待,清晰完整的答案:)”。我知道为什么它不起作用,但不知道如何解决它。但是当它到达callback(listProducts) 时进程停止了
    • 很抱歉。我忘记正确设置回调的this
    • 它运行良好,非常感谢 :) 你救了我的命。但我做了两处更改:我删除了arr.splice,并将variation.data 放入一个变量中,因为wait 内部的日期为NULL,你知道为什么吗?
    • 不,我不明白为什么会这样。以下是我在您的代码中看到的一些其他问题:a) 您两次使用相同的函数名称 (getInfosProducts)。这令人困惑。 b) 不应该有那么多全局变量(isClicklistProducts)。 c) getInfosProduct 根据其参数之一返回不同的类型。这是一种不好的做法。
    猜你喜欢
    • 2019-06-21
    • 2016-06-21
    • 2020-06-16
    • 2018-02-07
    • 1970-01-01
    • 2015-11-02
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多