使用casperjs时如何等待页面加载?

qwe*_*123 23 javascript phantomjs casperjs

我正在尝试抓取一个网页,其中包含许多下拉列表,并且表单中的值是相互依赖的.在许多方面,我需要代码等待页面刷新完成.例如,从列表中选择一个选项后,代码应该等到根据此选择填充下一个列表.如果有人可以指点,那将是非常有帮助的,因为奇怪的是我的代码只有在我提供了如此多的不必要的日志记录语句之后才能工作,这反过来又造成了一些延迟.任何改进代码的建议都会非常有用.

var casper = require('casper').create({
     verbose: true,
     logLevel: 'debug',
     userAgent: 'Mozilla/5.0  poi poi poi (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22',
     pageSettings: {}
 });

 casper.start('http://www.abc.com', function () {
     console.log("casper started");
     this.fill('form[action="http://www.abc.com/forum/member.php"]', {
         quick_username: "qwe",
         quick_password: "qwe"
     }, true);
     this.capture('screen.png');
 });
 casper.thenOpen("http://www.abc.com/search/index.php").then(function () {
     this.click('input[type="checkbox"][name="firstparam"]');
     this.click('a#poi');

     casper.evaluate(function () {
         document.getElementsByName("status")[0].value = 1;
         document.getElementsByName("state")[0].value = 1078;
         changeState(); //This function is associated with the dropdown ie state 
and the page reloads at this point. Only after complete refresh the code shoud execute! How can this be achieved?
         return true;
     });
     this.echo('Inside the first thenOpen' + this.evaluate(function () {
         return document.search.action;
     }));
 });
 casper.then(function () {
     this.capture("poi.png");
     console.log('just before injecting jquery');
     casper.page.injectJs('./jquery.js');
     this.click('input[type="checkbox"][name="or"]');
     this.evaluate(function () {
         $('.boxline .filelist input:checkbox[value=18127]').attr("checked", true);
     });
     this.echo('Just before pressing the add college button' + this.evaluate(function () {
         return document.search.action;
     }));
     this.capture('collegeticked.png');
     if (this.exists('input[type="button"][name="niv"]')) {
         this.echo('button is there');
     } else {
         this.echo('button is not there');
     }
     this.echo("Going to print return value");
     this.click('input[type="button"][name="poi"]'); // This click again causes a page refresh. Code should wait at this point for completion.
     this.echo('Immediately after pressing the add college btn getPresentState()' + this.evaluate(function () {
         return getPresentState();
     }));
     this.echo('Immediately after pressing add colleg button' + this.evaluate(function () {
         return document.search.action;
     }));
     this.capture('iu.png');
 });

 casper.then(function () {
     console.log('just before form submit');
     this.click('form[name="search"] input[type="submit"]'); //Again page refresh. Wait.
     this.echo('Immediately after search btn getPresentState()' + this.evaluate(function () {
         return getPresentState();
     }));
     this.echo('Immediately after search button-action' + this.evaluate(function () {
         return document.search.action;
     }));
     this.capture("mnf.png");
 });

 casper.then(function () {
     casper.page.injectJs('./jquery.js');
     this.capture("resultspage.png");

     this.echo('Page title is: ' + this.evaluate(function () {
         return document.title;
     }), 'INFO');
     var a = casper.evaluate(function () {
           return $('tbody tr td.tdbottom:contains("tye") ').siblings().filter($('td>a').parent());
     });
     console.log("ARBABU before" + a.length);
 });

 casper.run();
Run Code Online (Sandbox Code Playgroud)

Alg*_*lor 11

我一直在使用Arun在这里提到的waitForSelector'解决方法':https://stackoverflow.com/a/22217657/1842033

这是我发现的最佳解决方案; '缺点'就是你需要知道你期望加载什么元素.我说缺点,我个人认为我没有遇到过这样的情况:我没有得到某种 反馈说我无论等待的是什么都发生了

this.waitForSelector("{myElement}",
    function pass () {
        test.pass("Found {myElement}");
    },
    function fail () {
        test.fail("Did not load element {myElement}");
    },
    20000 // timeout limit in milliseconds
);
Run Code Online (Sandbox Code Playgroud)

虽然我猜你可以使用waitForResource()或类似的东西,如果你没有视觉反馈.


Peb*_*bbl 7

为了解决这个问题我已经采取了什么措施,当没有任何特定的目标并在重新加载的页面中等待时,是使用以下内容:

var classname = 'reload-' + (new Date().getTime()),
    callback = function(){},
    timeout = function(){};

/// It happens when they change something...
casper.evaluate(function(classname){
  document.body.className += ' ' + classname;
}, classname);

casper.thenClick('#submit'); /// <-- will trigger a reload of the page
casper.waitWhileSelector('body.' + classname, callback, timeout);
Run Code Online (Sandbox Code Playgroud)

这样我就不必依赖下一页中的特定预期元素,我基本上完成了反向操作.我已经创建了一个特定的选择器来注意,一旦选择器无法匹配,执行就会继续.

对于我的意图和目的,它足以知道页面已经开始重新加载,我不需要等到下一页完全重新加载.这样我就可以waitForSelector对重新加载之前和之后可能存在的元素触发某些调用.等到临时课程被删除后让我知道之前存在的任何东西都已被破坏,因此不必担心在重新加载之前选择元素.