我需要导航一个分页的网站,分页会激活一个Ajax请求,该请求会为页面带来新数据。
现在我有一个工作示例代码,等待20秒,然后点击链接(" ul.pageNavi li.next")。
url = 'https://www.somewebsite.com';
// open the url
var page = require('webpage').create();
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 5.2; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0';
page.open(url, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
window.setTimeout(function () { // Wait 20 seconds so the page loads
page.render('1.png');
// Begin - click on the pagination
page.evaluate( function() {
// find element to send click to
var element = document.querySelector( 'ul.pageNavi li.next' );
// create a mouse click event
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
// send click to element
element.dispatchEvent( event );
});
// End - click on the pagination
page.render('2.png');
phantom.exit();
}, 20000); // Change timeout as required to allow sufficient time
}
});
上面的代码正常运行,我成功进入了第2页。现在我陷入了实现循环的困境,所以我可以导航到以下页面。
我需要在每次点击之间等待几秒钟,我已实施此代码,但这不起作用。
url = 'https://www.somewebsite.com';
// open the url
var page = require('webpage').create();
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 5.2; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0';
page.open(url, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit();
} else {
window.setTimeout(function () { // Wait 20 seconds so the page loads
var morelinks = moreLinks();
var i = 0;
page.render(i + '.png');
console.log('1: ' + morelinks);
while (morelinks != 0) {
window.setTimeout(function () { // Wait 20 seconds so the page loads
i++;
// Begin
page.evaluate( function() {
// find element to send click to
var element = document.querySelector( 'ul.pageNavi li.next' );
// create a mouse click event
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, true, window, 1, 0, 0 );
// send click to element
element.dispatchEvent( event );
});
// End
page.render(i + '.png');
morelinks = moreLinks();
console.log('2: ' + morelinks);
}, 20000); // Change timeout as required to allow sufficient time
}
phantom.exit();
}, 20000); // Change timeout as required to allow sufficient time
}
});
function moreLinks() {
var morelinks = page.evaluate(function() {
return $('ul.pageNavi li.next').length;
});
return morelinks;
}
function getHref() {
var links = page.evaluate(function() {
return $('#ulSearchResults li a');
});
return links;
}
有人可以告诉我如何实现导航到以下页面吗?
答案 0 :(得分:1)
你有两个问题。
您正在处理异步函数(在循环中)。循环结束后,立即退出(phantom.exit()
)。此时,所有异步函数都没有开始执行。
如果从循环调用它们,您应该问自己如何评估异步函数。循环结束后,尚未执行任何功能。在第一次超时触发后,所有其他超时也会触发,因为setTimeout
基本上同时被调用。
有很多方法可以解决这个问题。这是两个:
按照从前一个函数延迟调用它们的方式安排超时。
while (morelinks != 0) {
// IIFE to keep a proper reference to `i`
(function(i){
setTimeout(function () {
// do your stuff
}, 20000 * i);
})(i);
i++;
}
在伪代码和真实代码之间混合。
function scrapePage(){
page.render(i + '.png');
if (exists(".next")) {
click(".next");
setTimeout(function (){
scrapePage();
}, 5000);
} else {
phantom.exit();
}
}
page.open(url, function(){
scrapePage();
});
关键是检查下一个按钮是否存在(或者是可见还是已启用),然后单击它。如果不是,那么您知道您已经在最后一页上,并且可以安全退出。
我们确定您可以自己实施exists()
和click()
功能。
waitFor
不要在第二个建议中等待静态时间,而是使用示例中的waitFor
函数等待页面完全加载,方法是查找适合的选择器装了最后一个。