如何使用PhantomJS浏览分页网站
How to navigate a paginated website with PhantomJS?
我需要浏览一个已分页的网站,分页会引发一个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;
}
有人能给我一个关于如何实现导航到以下页面的线索吗?
您有两个问题。
提前退出
您正在处理异步函数(在循环中)。循环结束后,您立即退出(phantom.exit()
)。此时,甚至没有一个异步函数开始执行。
异步函数的循环
您应该问问自己,如果异步函数是从循环中调用的,那么如何评估它们。循环结束后,还没有执行任何函数。在第一个超时触发之后,所有其他超时也会触发,因为setTimeout
基本上是同时调用的。
有很多方法可以解决这个问题。这里有两个:
1.静态超时延迟
以一种从上一个函数延迟调用超时的方式来安排超时。
while (morelinks != 0) {
// IIFE to keep a proper reference to `i`
(function(i){
setTimeout(function () {
// do your stuff
}, 20000 * i);
})(i);
i++;
}
2.递归(推荐)
伪代码和实代码的混合。
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
函数,通过查找最后加载的合适选择器来等待页面完全加载。
相关文章:
- 如何使用skip参数使用angular ui引导进行服务器端分页
- 如何通过引用var Using DataTables来进行分页或排序
- 使用CSS或JavaScript计算分页符的数量
- DataTables-创建自定义分页样式(加载更多样式)
- 带有url的单页网站导航
- 使用ajax的服务器端分页&jQuery
- 分页:如何用AJAX加载第一个页面
- dataTables-如何自定义分页类型以显示最后一个页码后面的省略号,
- 如何在一页网站中使用PHP重定向到一个页面
- 不带jquery的全屏分页
- 更改组合框分页后,getValue和getRawValue返回相同的值
- jQuery简单分页
- 使用jQuery在表中分页
- jQuery分页下一页和上一页按钮在点击零或超过最后一页后失败
- jQuery:根据select选项中的每页项目进行分页
- 如何使用PhantomJS浏览分页网站
- 如何以反向/从右到左的顺序显示阿拉伯语网站的Nivo滑块分页
- 如何使用剃须刀在Umbraco网站中实现分页搜索
- 动态网站的分页头
- 静态网站中的表分页问题