噩梦条件等待()

use*_*ser 3 javascript web-crawler node.js nightmare

我正在尝试使用 Nightmare 抓取网页,但希望等待#someelem出现,前提是它确实存在。否则,我想让 Nightmare 继续前进。这如何使用.wait()

我不能用.wait(ms)。Using.wait(selector)表示 Nightmare 会一直等待直到元素出现,但如果页面永远不会有这个元素,Nightmare 会一直等待。

最后一个选项是使用.wait(fn). 我试过这样的事情

.wait(function(cheerio) {
            var $ = cheerio.load(document.body.outerHTML);
            var attempt = 0;

            function doEval() {
                if ( $('#elem').length > 0 ) {
                    return true;
                }
                else {
                    attempt++;

                    if ( attempt < 10 ) {
                        setTimeout(doEval,2000); //This seems iffy.
                    }
                    else {
                        return true;
                    }
                }
            }

            return doEval();
        },cheerio)
Run Code Online (Sandbox Code Playgroud)

因此,等待并再次尝试(达到阈值),如果未找到该元素,则继续前进。setTimeout 周围的代码似乎是错误的,因为.wait它是在浏览器范围内完成的。

提前致谢!

Ros*_*oss 5

我不认为通过cheerio你拥有的图书馆会很好地工作。参数被序列化(或多或少)以传递给子电子进程,因此传递整个库可能不起作用。

从好的方面来说, 的fn部分.wait(fn)在页面上下文中执行 - 这意味着您可以完全访问document它及其拥有的方法(例如,querySelector)。如果存在,您还可以访问页面的 jQuery 上下文,如果不存在,您甚至可以使用.inject()它来注入它。

撇开这一点不谈,就.wait()(并且.evaluate(),就此而言)期望同步方法是正确的,至少在可以直接在.evaluate().

在可用之前,您可以.action()用来模仿您想要的行为:

var Nightmare = require('nightmare');

Nightmare.action('deferredWait', function(done) {
  var attempt = 0;
  var self = this;

  function doEval() {
    self.evaluate_now(function(selector) {
      return (document.querySelector(selector) !== null);
    }, function(result) {
      if (result) {
        done(null, true);
      } else {
        attempt++;
        if (attempt < 10) {
          setTimeout(doEval, 2000); //This seems iffy.
        } else {
          done(null, false);
        }
      }
    }, '#elem');
  };
  doEval();
  return this;
});

var nightmare = Nightmare();
nightmare.goto('http://example.com')
  .deferredWait()
  .then(function(result) {
    console.log(result);
  });
Run Code Online (Sandbox Code Playgroud)

  • 我想现在不需要这个了,因为我们可以使用`.wait('#elem')`,对吗? (2认同)