这几天在做爬虫的东西,腾讯的登录真能把人搞死。。。
首先是对http头做了校验,一旦顺序或者大小写不对,立马报403错误,然后最后密码加密那块md5 + salt + RSA + 还有自创的TEA加密,我完全被搞晕了。
只能说它们的安全措施是做得非常好的,我搞了几天,完全用它的JS代码,本来还有希望的,今天再一看,登录相关的逻辑又改了。。。
所以,为了以后不蛋疼,想到用简单粗暴点的方案,直接模拟浏览器登录,搜了下,zombie还有phantomjs都可以,但phantomjs似乎重了点,先拿zombie试试:github.com/assaf/zombi…
npm install zombie --save
这个项目看起来是做了很久了,但是最新的文档很差,我看了以前的文档是有的。
如下是个登录后取得cookie的例子:
function async getCookies(username, password) {
// browser.debug();
// browser.userAgent = ua;
await browser.visit('http //example.com/login');
await browser.wait({
duration: '10s',
element: '#submit',
});
await browser
.fill('username', account.username)
.fill('password', account.password)
.click('#submit');
return browser.cookies
}
缺点
太慢;
耗内存;
优点
能模拟真实用户登录;
可以在一定程度上绕过对方系统的反爬虫机制;
对于像腾讯登录那样复杂的前端加密验证可以简单绕过解决;
发现zombie.js还是太弱了,很多地方不能满足需求,包括request的HTTP头也不合乎标准,于是硬着头去尝试下PhantomJS。
这一试,我就后悔了,这么好的东西我居然不先尝试!怎么说呢,它比zombie好用太多,加载处理速度方面也是远远超过。唯一比较遗憾的是没有原生的nodejs接口,它只是一个环境,像mocha这样有自定义的变量,需要用它去执行js文件。所以如果要用到爬虫上面的话,需要通过第三方的包去包装一层。比如我用的github.com/amir20/phan…
目前我没找到这个库一些常用的方法utils,比如waitFor之类的没有实现,所以只能手动实现了,下面贴出我自己实现的:
async function waitFor(testFx, {
timeout = 3000,
delay = 100,
silence = false,
}) {
function sleep(t) {
return new Promise((resolve) => {
setTimeout(resolve, t);
});
}
const start = new Date().getTime();
async function _waitFor() {
if (new Date().getTime() - start > timeout) {
const e = new Error('Timeout');
if (silence) return e;
throw e;
}
const result = await testFx();
if (!result) {
await sleep(delay);
return await _waitFor();
}
}
return await _waitFor();
}
当然了,其他成熟的框架也有,比如
SlimerJS
跟PhantomJS几乎一样,API接口一致,但是没有PhantomJS不能获取response body的问题,是个替代品,但是它是基于Gecko的
CasperJS
包装了PhantomJS以及SlimerJS,提供了一些语法糖,高层实现,挺适合做e2e测试的
SpookyJS
基于CasperJS,提供了nodes的API,就相当于上面phantomjs-node对PhantomJS封装,如果下次再做的话,我会考虑这个包。