【问题标题】:Return list of Objects with Node js使用 Node js 返回对象列表
【发布时间】:2017-05-25 12:20:43
【问题描述】:

我最近开始开发 Node js 应用程序,它在控制器中使用 Selenium 从网页中获取项目列表,我想将获取的项目列表作为 JSON 响应返回。

exports.read_all_products = function (req, res) {
    var driver = new webdriver.Builder().forBrowser('phantomjs').build();
    driver.get('https://www.test.com/products?PC=' +req.params.category);    
    driver.wait(until.elementLocated(By.className('product-slide-all')), 20000, 'Could not locate the element within the time specified');

    driver.findElements(By.className("product-slide-all")).then(function (elements) {
        var arr = [];
        elements.forEach(function (element) {
        element.getAttribute("innerHTML").then(function (html) {
            const dom = new JSDOM(html);
            var obj = new Object();
            obj.product_name = dom.window.document.querySelector(".product-name").textContent;
            obj.product_code = dom.window.document.querySelector(".product-code").textContent;
            obj.price = dom.window.document.querySelector(".product-price").textContent;
            arr.push(obj);
        });
    });
    res.json(arr);
    });
}

问题是我总是得到一个空的 JSON 响应,即使项目已添加到数组中。我想知道处理这种情况的正确方法。

谢谢。

【问题讨论】:

  • 您可以尝试将您的res.json(arr); 上移一级吗? (在}); 之前)?
  • 不,然后我收到一条错误消息,提示“发送后无法设置标题”。
  • 哦。在这种情况下,您可以尝试将您的res.json(arr); 改写为JSON.parse(JSON.stringify(arr)) 吗?
  • 我仍然遇到同样的错误,我认为这是因为 res.json(JSON.parse(JSON.stringify(arr))) forEach 循环。
  • 有什么方法可以用 promises 做吗?

标签: javascript node.js selenium


【解决方案1】:

看起来问题是因为 Selenium 正在运行一个异步进程,因此响应立即返回,因为没有任何东西阻止它。

findElements 返回一个 Promise,您需要从中返回响应。

看看How do I return the response from an asynchronous call?

【讨论】:

    【解决方案2】:

    终于在 webdriver.promise.map 的帮助下,我得以实现它。

    将 Web 驱动程序 HTML 提取移动到单独的函数中。

    var findItems = function (category) {
    var driver = new webdriver.Builder().forBrowser('phantomjs').build();
    var map = webdriver.promise.map;
    driver.get('https://www.test.com?PC=' + category);
    driver.wait(until.elementLocated(By.className('product-slide-all')), 30000, 'Could not locate the element within the time specified');
        var elems = driver.findElements(By.className("product-slide-all"));
            return map(elems, elem => elem.getAttribute("innerHTML")).then(titles => {
            return titles;
        });
    }
    

    然后从下面的响应处理函数中调用它,

    exports.read_all_products = function (req, res) {
    findItems(req.params.category).then(function (html) {
        var value;
        var arr = [];
        Object.keys(html).forEach(function (key) {
            value = html[key];
            const dom = new JSDOM(value);
            var obj = new Object();
            obj.product_name = dom.window.document.querySelector(".product-name").textContent;
            obj.product_code = dom.window.document.querySelector(".product-code").textContent;
            obj.price = dom.window.document.querySelector(".product-price").textContent;
            arr.push(obj);
        });
        res.json(arr);
    })
    };
    

    this stack overflow answers 中有描述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 2015-01-05
      • 2015-11-11
      相关资源
      最近更新 更多