我是PhantomJS的新手.我想加载一个页面,删除它的链接,然后依次打开每个页面,一个一个,甚至每个请求之间延迟.我遇到麻烦让一个人开火,所以我想也许我可以使用承诺来解决这个问题,但我不认为节点库与Phantom一起工作.我到目前为止看到的每个例子都打开了一个页面,然后退出.
这就是我所得到的:
var page = require('webpage').create(); page.open('http://example.com/secretpage',function(status) { console.log(status); if(status !== 'success') { console.log('Unable to access network'); } else { var links = page.evaluate(function() { var nodes = []; var matches = document.querySelectorAll('.profile > a'); for(var i = 0; i < matches.length; ++i) { nodes.push(matches[i].href); } return nodes; }); links.forEach(function(link) { console.log(link); page.open(link,function(status) { // <---- tries opening every page at once console.log(status); var name = page.evaluate(function() { return document.getElementById('username').innerHTML; }); console.log(name); page.render('profiles/'+name + '.png'); }); }); } // phantom.exit(); });
有没有办法按顺序打开每个链接?
解决方法
对于这种典型情况,我使用
async.js,特别是队列
component.
这是一个非常基本的实现
phantom.injectJs('async.js'); var q = async.queue(function (task,callback) { page.open(task.url,function(status) { // <---- tries opening every page at once if(status !== 'success') { console.log('Unable to open url > '+task.url); } else { console.log('opened '+task.url); //do whatever you want here ... page.render(Date.now() + '.png'); } callback(); }); },1); // assign a callback q.drain = function() { console.log('all urls have been processed'); phantom.exit(); } var page = require('webpage').create(); page.open('http://phantomjs.org/',function(status) { console.log(status); if(status !== 'success') { console.log('Unable to access network'); } else { var links = page.evaluate(function() { var nodes = []; var matches = document.querySelectorAll('a'); for(var i = 0; i < matches.length; ++i) { nodes.push(matches[i].href); } return nodes; }); links.forEach(function(link) { q.push({url: link},function (err) { console.log('finished processing '+link); }); }); } });
URL被添加到队列中并且将被并行处理(达到并发限制,一个在这里).我重复使用相同的页面实例,但这不是强制性的.
像过去我已经做过这样的爬虫了,我再给你两个建议:
>不要加载图像以加快测试速度> href有时是相对的,所以先检查一下它是否是一个有效的url