无头浏览器phantomjs

所谓的无头浏览器(headless)就是指不带界面,完全可以命令行or脚本控制的浏览器。

phantomjs 就是比较流行的无头浏览器。

  • 基于webkit
  • 可以解析流行网页内的js脚本。
  • 可以把网页后台渲染成图片
  • 可以通过脚本扩展功能,这点在采集/自动化测试内很有用。

缺点也有,和普通的基于页面分析的采集来比较,这个phantomjs重了很多。

官网:http://phantomjs.org/

使用教程:http://phantomjs.org/documentation/

例子:http://phantomjs.org/examples/

在采集中,使用无头浏览器,一般是因为页面存在权限验证、复杂的防采集js脚本。在这种情况下,分析页面内的js脚本,一一反解析,是很麻烦的。如果量不大或者只是在登陆的时候使用,使用无头浏览器自动获取登陆cookie或者干脆直接采集数据是很好的选择。

举个例子:

一个京东的推广链接。

1
http://union.click.jd.com/jda?e=&p=AyIOZRprFwMVD1IeXyVGTV8LRGtMR1dGXgVFTUdGW0pADgpQTFtLGVoSChUCUQQCUF5PN1d8BR1dZQcmeV9jf2AdBV8PQFJWGSUXVyUEGgdWHlsQMhcEXRJrEFxlTCdYH1N5QQBSWScXXBBaBis6ZzJEaVUaWhQDEwVWHlIlAyIHUBJbFQQWB1MYXxYFIgBlWANFXVdUC1NrJTIi&t=W1dCFBBFC1pXUwkEAEAdQFkJBVkUBRoAUB9ETEdOWg%3D%3D&a=fCg9UgoiAwwHO1BcXkQYFFlhfnl1fVNfRl0zVRBSUll%2bAQAPDSwjLw%3d%3d&refer=http%3a%2f%2fgo.smzdm.com%2fd3b5b4f507648347%2fca_aa_yh_27_6724898_135_399_31

如果你想知道这货指到那个jd物品上,curl这个链接,某些时候,你会得到一个302 redirect。这个结果不错。

但是,某些时候,会得到:

1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="renderer" content="webkit"><title>京东网上商城</title></head><body><script language='javascript' type='text/javascript'>function htmlspecialchars(str){ str = str.replace(/</g, '&lt;'); str = str.replace(/>/g, '&gt;'); str = str.replace(/"/g, '&quot;'); str = str.replace(/'/g, '&#039;'); return str; } var CookieAds={enabled:function(e){var c=!1;'string'===typeof this.get(e)&&(c=!0);return c},set:function(e,c,b){b=b||{};b.domain=b.domain||'';b.path=b.path||'/';b.expires=b.expires||31536E6;if('number'==typeof b.expires){var d=new Date;d.setTime(d.getTime()+b.expires)}document.cookie=e+'='+c+';expires='+d.toGMTString()+(b.domain?';domain='+b.domain:'')+';path='+b.path},get:function(e){e=encodeURIComponent(e)+'=';var c=document.cookie.indexOf(e),b=null;-1<c&&(b=document.cookie.indexOf(';',c),-1==b&& (b=document.cookie.length),b=decodeURIComponent(document.cookie.substring(c+e.length,b)));return b},uuid:function(){var e=Math.round(2147483647*Math.random()),c;c={};var b=window,d=b.navigator,b=b.screen,f=document;c.D=b?b.width+'x'+b.height:'-';c.C=b?b.colorDepth+'-bit':'-';c.language=(d&&(d.language||d.browserLanguage)||'-').toLowerCase();c.javaEnabled=d&&d.javaEnabled()?1:0;c.characterSet=f.characterSet||f.charset||'-';d=window.navigator;c=d.appName+d.version+c.language+d.platform+d.userAgent+ c.javaEnabled+c.D+c.C+(document.cookie?document.cookie:'')+(document.referrer?document.referrer:'');d=c.length;for(b=window.history.length;0<b;)c+=b--^d++;return e^0},initjda:function(){var e;this.enabled('__jda')||(a=Date.parse(new Date).toString().substring(0,10),e=this.uuid(),this.set('__jda','123.'+e+'.'+a+'.'+a+'.'+a+'.0',{expires:15552E6,domain:'.jd.com'}));return e}};CookieAds.initjda(); hrl='http://union.click.jd.com/jda?e=&p=AyIHZRprFQAQD10bWSVGTV8LRGtMR1dGXgVFTUdGW0pADgpQTFtLG1kXChoHVwQCUF5PNx15PWVpEhkheRtdRm5kAGktYwoTRSUXVyUDIgdUGloUBRMEUR5rJWNgNx51WiUHEQFRH1kdCxU3VR5SFQIUA1EaXhULFzdXG2tXW0JMC0VrJQ%3D%3D&t=W1dCFBBFC1pXUwkEAEAdQFkJBVsXABoPVRlETEdOWg%3D%3D&a=fCg9UgoiAwwHO1BcXkQYFFlhfnl1fVNbQFszVRBSUll%2bAQAPDSwjLw%3d%3d&refer=norefer' ;(function (){ if (top.location != self.location) { return false; } var tu = unescape(self.location); if (htmlspecialchars(tu).length != tu.length) { exit; }if (tu && ((tu.indexOf("http://union.click.jd.com/")===0) || (tu.indexOf("https://union.click.jd.com/")===0))) { if (!window.attachEvent) {document.write('<input style="display:none" type="button" id="exe" value="" onclick="window.location=\''+hrl+'\'">'); document.getElementById('exe').click(); } else { document.write('<a style="display:none" href="'+hrl+'" id="exe"></a>'); document.getElementById('exe').click();} }})(hrl);</script></body></html>

读混淆过的js代码,实际上是没啥意思的。而且,对方略微修改下算法,加入随机因子,反混淆的工作量就直线加大……

所以,这里直接干脆就把无头浏览器phantomjs用上,虽然慢一点,但是就不需要分析了。

同理,可以利用这个搞定复杂的登陆采集,诸如淘宝的登陆……