简单试了一下 CasperJS ,基于PhantomJS引擎。
可以不搞图形窗口出来就网页截图,非常方便,值得一用。
示例集合:tests/suites/casper
Windows下安装过程:
1、在http://casperjs.org/下载zip文档,解压,把 casperjs/batchbin/ 目录加入PATH环境变量
2、在http://phantomjs.org/下载zip文档,解压,把 phantomjs 目录加入PATH环境变量
目前发现的问题:
- 网页内容比较长的时候,windows下有时会crash掉
- post到https的表单不成功(加ignore-ssl-errors就好了),windows下参考 https://github.com/n1k0/casperjs/issues/49#issuecomment-23147718
写个小demo练手,把指定歌曲批量加入百度音乐收藏:baidu_music
代码示例:0320-casperjs
以登录百度为例
//初始化
//打log
//var casper = require('casper').create({logLevel: 'debug', verbose: true});
//不下载图片,不下载flash等等,可加速网页载入
var casper = require('casper').create({
pageSettings: {
loadImages: false, // do not load images
loadPlugins: false // do not load NPAPI plugins (Flash, Silverlight, ...)
}
});
//指定user-agent
casper.userAgent('Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:18.0) Gecko/20130119 Firefox/18.0');
//文件处理
var fs = require('fs');
//命令行参数
var usr = casper.cli.get(0);
var passwd = casper.cli.get(1);
var cookie_file = casper.cli.get(2);
//控制台输出
console.log("login baidu" );
//打开一个页面,有时要wait 1s再点击,不然有些js没load完,点击不生效
var login_url = 'https://passport.baidu.com/v2/?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2F';
casper.start(login_url);
casper.wait(1000, function(){
this.click('#pass-user-login');
});
//提交一个表单
casper.thenEvaluate(function(usr,passwd) {
document.querySelector('#TANGRAM__3__userName').setAttribute('value', usr);
document.querySelector('#TANGRAM__3__password').setAttribute('value', passwd);
}, { 'usr' : usr, 'passwd' : passwd });
casper.wait(1000, function () {
this.click('#TANGRAM__3__submit');
});
//把cookie写入文件
casper.wait(1000, function () {
var cookies = JSON.stringify(phantom.cookies);
fs.write(cookie_file, cookies, 644);
console.log("write cookie file : " + cookie_file +"\n");
});
//执行
casper.run();
以查找百度音乐为例
//从文件读入cookie
var cookie_file = casper.cli.get(0);
var data = fs.read(cookie_file);
phantom.cookies = JSON.parse(data);
//根据xpath表达式定位dom元素
var x = require('casper').selectXPath;
//...
var artist = "周华健";
var title="风雨无阻";
casper.then(function(){
var song_x = artist ? '//a/em[text()="' + artist + '"]//ancestor::div[@class="song-item clearfix"]' : '';
song_x +="//span[@class='song-title']//a[@title='" + title + "']";
var collect_x = x(song_x);
if (this.exists(collect_x)) {
var id = this.getElementAttribute(collect_x,'href');
song_id = id.replace(/#.*/, '').replace(/^.*\//, '');
}
});
以收藏百度音乐为例
casper.then(function(){
if(song_id==0) return;
var collect_url = 'http://music.baidu.com/song/' + song_id;
this.thenOpen(collect_url, function(){
console.log("visit url : " + collect_url);
var collect_x = x('//span[text()="收藏"]/parent::span/parent::a');
if (this.exists(collect_x)) {
console.log("click collect button : "+song_id);
this.click(collect_x);
}
this.wait(1000, function() {
var artist = this.getElementAttribute('span[class="author_list"]', 'title')
var title = this.fetchText('span[class="name"]');
status = this.fetchText('div[class="song-page-share clearfix"] span span');
status = status.replace('分享','');
console.log("song "+ artist + "《 " + title +" 》 : " + status+"\n");
});
});
});
支持指定FRAME点击其中的元素
这个参考github上官方给的例子就行了 tests/suites/casper/frames.js
不像perl的Win32::IEAutomation,点击frame里面的 <a onclick="javascript: xxx();">yyy</a> 总是失败,哎。。。
特定event出现时的处理
看官方介绍 Hook in the deep using events,包括各种触发事件,例如mousemove,弹alert,page载入完毕等等
casper.on('http.status.404', function(resource) { this.log('Hey, this one is 404: ' + resource.url, 'warning'); });
打印变量详情
require('utils').dump(x);
载入JQquery或其他本地JS
远程DOM能用:casper.page.injectJs('/path/to/jquery.js');
casperjs run着就一直能用:
var casper = require('casper').create({ clientScripts: ["includes/jquery.min.js"] });
设置Referer
var casper = require('casper').create();
casper.start().then(function() {
this.page.customHeaders = {
"Referer" : "http://video.ustc.edu.cn/"
};
});
casper.thenOpen('http://202.38.64.10/').run();
没有评论:
发表评论