使用python/casperjs编写终极爬虫-客户端App的抓取
2015-07-23 16:08
936 查看
1.缘起
随着移动互联网的发展,现在写web和我三年前刚开始写爬虫的时候已经改变了太多。特别是在node以及javascript/ruby社区的努力下,以往“服务器端”做的事情都慢慢搬到了“浏览器”来实现,最极端的例子可能是meteor了 ,写web程序无需划分前端后端的时代已经到来了。。。在这一方面,Google一向是最激进的。纵观Google目前的产品线,社交的Google Plus,网站分析的Google Analytics,Google目前赖以生存的Google Adwords等,如果想下载源码,用ElementTree来解析网页,那什么都得不到,因为Google的数据都是通过Ajax调用经过数据混淆处理的数据,然后用JavaScript进行解析渲染到页面上的。
本来这种事情也不算太多,忍一忍就行了,不过最近因业务需要,经常需要上Google的Keyword Tools来分析特定关键字的搜索量。
图为关键字搜索的截图
图为Google经过混淆处理的Ajax返回结果。
要把这么费劲的事情自动化倒也不难,因为Google也提供了API来做,Adwords项目的TargetingIdeaService就是来做这个的,问题是Google的API调用需要花钱,而如果能用爬虫技术来爬取这个结果,就能省去不必要的额外开销。
2. Selenium WebDriver
由于要解析执行复杂的JavaScript,必须有一个Full Stack的浏览器JavaScript环境,这种环境三年前的话,可能只能诉诸于于selenium,selenium是一款多语言的浏览器Driver,它最大的优点在于,提供了从命令行统一操控多种不同浏览器的方法,这极大地方便了web产品的兼容性自动化测试。2.1 在没有图形界面的服务器上安装和使用Selenium
安装selenium非常简单,pip install selenium 即可,但是要让firefox/chrome工作,没有图形界面的话,还是要费一番功夫的。推荐的做法是
123 | apt-get install xvfbXvfb :99 -ac -screen 0 1024x768x8&export DISPLAY=:99 |
2.2 爬取Keywords
先总结一下Adwords的使用方法吧,要能正常使用Adwords,必须要有一个开通Adwords的Google Account,这倒不是很难,只要访问 http://adwords.google.com ,Google会协助创建账号,如果还没有的话,其次就是登陆了。通过分析登陆页面,我们可以看到需要在id为Email的一个input框内输入email,然后在id为Passwd的密码框内输入密码,然后点击Sign in提交这个页面内唯一的form。首先别忘了开一个浏览器先
在这里,我们要等待Search按钮在浏览器中出现以后,才能确认网页加载完毕,Selenium WebDriver有两种方式可以实现这一点,我偷懒用了全局的默认等待机制:
3. JavaScript Headless解决方案随着Node以及随之而来的JavaScript社区的进化,如今的我们就幸福多了。远的我们有phantomjs, 一个Headless的WebKit Driver,意味着可以无需GUI,完全模拟Chrome/Safari的操作。 近的有casperjs(基于phantomjs的好用封装),zombie(相比phantomjs的优势是可以和node集成)等。其中非常可惜地是,zombiejs似乎对富JavaScript网站支持得有问题,所以后来我还是只能用casperjs来进行测试。Headless的方案因为不需要渲染GUI,执行速度约为Selenium方案的三倍。另外由于这是纯JavaScript的方案,于是我们可以直接在例如Chrome的Console模式下写代码控制浏览器,不存在如Selenium那样还需要语义转换,非常简洁直观。例如利用W3C Selectors API Level 1所提供的querySelector来快速选取元素,对表单进行submit,对按钮进行click,甚至可以执行自定义JavaScript脚本以便按一定规律对页面进行操控。但是casperjs或者说phantomjs的弱点是不支持除了文件读写和浏览器操作以外的一切*nix IPC惯用伎俩,socket神马的统统不支持,1.4版本以后才加入了一个webserver用于和外界通信,但是用httpserver来和外界通信?我有点抵触就是了。废话不说了,casperjs的代码看起来就是这样,登陆:
值得一提的是,casperjs一定要调用casper.run方法,之前的start, then等方法,只是把步骤封装到了this._steps里面,只有在run的时候才会真正执行,所以casperjs设计流程的时候会很痛苦,for/each之类的手法有时并不好用。 这个时候需要用JavaScript编程比较常用的递归化的方法,参见https://github.com/n1k0/casperjs/blob/master/samples/dynamic.js 这个例子。我在完整的casperjs代码里面也是这么做的。 具体逻辑的实现和selenium类似,我就不废话了,完整的例子参见: https://gist.github.com/3798922 4. 综上介绍了selenium和casperjs两种不同的终极爬虫写法,但是其实这篇文写来只是太久没更新了,写点东西更新一下而已:) |
相关文章推荐
- Android Studio常用快捷键
- Android 控件:CheckBox
- 论我的ios之路_第2期
- ios 后台数据请求AFNetwork常遇见的1016错误与3840错误的解决方法
- Unity3D-client +MinaServer仿微信聊天系统
- 【转】Android自动化测试之MonkeyRunner录制和回放脚本(四)
- 论我的ios之路_第1期
- Android Hook Java
- android APK应用安装过程以及默认安装路径
- Android 百分比布局支持库介绍
- Android 进阶
- Android基础_活动_生命周期
- android studio使用遇到问题
- Android adb 发送广播、启动Activity、Service等
- ios开发 <AppName>-Prefix.pch文件的用法详解
- Android照片墙完整版,的完美结合LruCache和DiskLruCache
- Android 反编译
- 微信应用签名生成工具
- Android学习笔记之AndroidManifest.xml文件解析 service
- [Object-C] AutoLaout入门