梦魇条件等待() [英] Nightmare conditional wait()

查看:91
本文介绍了梦魇条件等待()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Nightmare抓取网页,但希望等待 #someelem 出现,只有它确实存在。否则,我想让梦魇继续前进。怎么能用 .wait()完成?

I'm trying to crawl a webpage using Nightmare, but want to wait for #someelem to be present, only if it actually exists. Otherwise, I want Nightmare to move on. How can this be done using .wait()?

我不能用 .wait(MS)。使用 .wait(selector)意味着Nightmare会一直等到元素存在,但如果页面永远不会有这个元素,Nightmare会一直等待。

I can't use .wait(ms). Using .wait(selector) means Nightmare will keep waiting until the element is present, but if the page will never have this element, Nightmare will keep waiting forever.

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

The last option is to use .wait(fn). And I've tried something like this

.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)

所以,等待并再次尝试(达到阈值) ),如果找不到元素,那么继续前进。 setTimeout周围的代码似乎有误,因为 .wait 是在浏览器范围内完成的。

So, wait and attempt again (upto a threshold), and if the element is not found, then just move on. The code seems wrong around setTimeout, because .wait is done at the browser-scope.

提前致谢!

推荐答案

我不认为你传递 cheerio 库它会很好地运作。参数被序列化(或多或少)以传递给子Electron进程,因此传递整个库可能不起作用。

I don't think passing the cheerio library as you have it is going to work very well. The arguments get serialized (more or less) to be passed to the child Electron process, so passing an entire library probably won't work.

在上方, fn .wait(fn)的一部分在页面上下文中执行 - 意味着您拥有对<$ c的完全访问权限$ c> document 及其拥有的方法(例如 querySelector )。您也可以访问页面的jQuery上下文(如果存在),或者您甚至可以使用 .inject()来注入它。

On the up side, the fn part of .wait(fn) is executed in the page context - meaning you have full access to document and the methods it has (eg, querySelector). You could also have access to the page's jQuery context if it exists, or you could even use .inject() to inject it if not.

除此之外,你是正确的 .wait()(和 .evaluate(),就此而言)期望一种同步方法,至少在承诺可以使用之前直接在 .evaluate()

Setting that aside, you're right insofar as .wait() (and .evaluate(), for that matter) expect a synchronous method, at least until something like promises could be used directly in .evaluate().

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

Until that is available, you could use .action() to mimic the behavior you want:

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);
  });

这篇关于梦魇条件等待()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆