苹果icloud邮箱抓取
2016-06-17 18:51
211 查看
1 icloud登录,与其他网站登录区别
1.1 支持pop抓取的邮箱:pop提供统一接口,抓取简单;
1.2 没有前端js加密的邮箱(139,126,163):只要代码正确模拟登录流程,参数正确,即可正确爬取邮箱;
1.3 需要前端js加密(sina邮箱web端,微博):前端用户名密码需要js加密,加密算法各网站不同。通常需要模拟js加密(可以自己写php,java模拟js,也可以通过其他方式直接运行js代码得到结果,java就可以直接调用js代码,php可通过phantomjs获取js加密结果),得到加密后用户名密码以及正确的模拟登录流程就能实现成功登录;
1.4 icloud登录就比较特殊:
1:几乎整个页面都是js生成,极少原生html标签;
2:登录框还内嵌到iframe里;
3:一个首页登录页面有105 requests,流量846kb,耗时14.79s。而且js非常复杂,11个js文件,还被混淆过。用代码模拟登录这条路估计很难走通。
2 抓取工具选择
2.1 考虑到icloud登录复杂,适宜于选择PhantomJS或Selenium来模拟浏览器行为爬取网页;
2.2 Selenium 是一款Web应用自动测试工具,使用它我们可以完全模拟用户行为对Web页面进行操作。它本身支持多种浏览器引擎,但都需要安装相应浏览器的driver,如使用Chrome 的话必须要安装一个ChromeDriver。对于没有图形界面的server环境,Selenium会因无法调取服务器图形界面相应接口而无法使用。
2.3 PhantomJS 是一个不需要图形界面,基于Webkit的javascript引擎.适用于运行在服务器上的, 资源占用相对小于Selenium;
2.4 综上适合选择PhantomJS作为爬虫的引擎。
3 icloud抓取流程
1 加载登录首页 https://www.icloud.com/ :完全加载比较耗时,一般15s以上。
(以下图片都是phantomjs模拟登录过程的截图,具体phantomjs代码在第4部分)
加载中页面
登录页加载完成
2 输入用户名密码。
2.1 跳转到iframe页:由于登录窗口是内嵌的iframe中,由于跨域访问而无法直接获取iframe中DOM元素,所以需要先跳转到iframe;
2.2 添加单击事件输入用户名:icloud登录必须先输入用户名和密码,然后才会出现一个小箭头,二者缺一小箭头就无法单击也就无法登录。
2.3 添加单击事件输入密码:
2.4 单击小箭头图标,登录icloud:
2.5 除了单击小箭头图标,也可以输入完用户名密码后回车,实现登录请求:
先输入用户名,箭头图标为灰色,不能点击
用户名密码都输入后箭头图标变黑色,可单击登录,也可focus到密码框回车登录
成功登录icloud首页
3 单击“邮件”小图标,登录邮箱:
单击邮箱图标后“努力加载中”
单击邮箱图标后“努力加载中”
4 成功进入icloud邮箱,就可以进行抓取和解析工作了。
4 代码实现
4 phantomjs执行命令(linux)
4.1 以上代码存为一个js文件,如:/home//phantomjsfile/icloudCrawler.js
4.2 新建文件夹存储cookie,如:/home/phantomjsfile/cookies
4.3 执行phantomjs语句:
phantomjs --cookies-file=/home/phantomjsfile/cookies --debug=yes --ignore-ssl-errors=true --web-security=no --ssl-protocol=any /home/phantomjsfile/icloudCrawler.js
--debug : 会输出debug信息
--ignore-ssl-errors :忽视加密的ssl连接错误
--web-security :好象是忽略加密传输之类的,不加会请求失败
希望能对你有所帮助.
结束!!
1.1 支持pop抓取的邮箱:pop提供统一接口,抓取简单;
1.2 没有前端js加密的邮箱(139,126,163):只要代码正确模拟登录流程,参数正确,即可正确爬取邮箱;
1.3 需要前端js加密(sina邮箱web端,微博):前端用户名密码需要js加密,加密算法各网站不同。通常需要模拟js加密(可以自己写php,java模拟js,也可以通过其他方式直接运行js代码得到结果,java就可以直接调用js代码,php可通过phantomjs获取js加密结果),得到加密后用户名密码以及正确的模拟登录流程就能实现成功登录;
1.4 icloud登录就比较特殊:
1:几乎整个页面都是js生成,极少原生html标签;
2:登录框还内嵌到iframe里;
3:一个首页登录页面有105 requests,流量846kb,耗时14.79s。而且js非常复杂,11个js文件,还被混淆过。用代码模拟登录这条路估计很难走通。
2 抓取工具选择
2.1 考虑到icloud登录复杂,适宜于选择PhantomJS或Selenium来模拟浏览器行为爬取网页;
2.2 Selenium 是一款Web应用自动测试工具,使用它我们可以完全模拟用户行为对Web页面进行操作。它本身支持多种浏览器引擎,但都需要安装相应浏览器的driver,如使用Chrome 的话必须要安装一个ChromeDriver。对于没有图形界面的server环境,Selenium会因无法调取服务器图形界面相应接口而无法使用。
2.3 PhantomJS 是一个不需要图形界面,基于Webkit的javascript引擎.适用于运行在服务器上的, 资源占用相对小于Selenium;
2.4 综上适合选择PhantomJS作为爬虫的引擎。
3 icloud抓取流程
1 加载登录首页 https://www.icloud.com/ :完全加载比较耗时,一般15s以上。
(以下图片都是phantomjs模拟登录过程的截图,具体phantomjs代码在第4部分)
加载中页面
登录页加载完成
2 输入用户名密码。
2.1 跳转到iframe页:由于登录窗口是内嵌的iframe中,由于跨域访问而无法直接获取iframe中DOM元素,所以需要先跳转到iframe;
2.2 添加单击事件输入用户名:icloud登录必须先输入用户名和密码,然后才会出现一个小箭头,二者缺一小箭头就无法单击也就无法登录。
2.3 添加单击事件输入密码:
2.4 单击小箭头图标,登录icloud:
2.5 除了单击小箭头图标,也可以输入完用户名密码后回车,实现登录请求:
先输入用户名,箭头图标为灰色,不能点击
用户名密码都输入后箭头图标变黑色,可单击登录,也可focus到密码框回车登录
成功登录icloud首页
3 单击“邮件”小图标,登录邮箱:
单击邮箱图标后“努力加载中”
单击邮箱图标后“努力加载中”
4 成功进入icloud邮箱,就可以进行抓取和解析工作了。
4 代码实现
//方法:循环等待,直到方法执行完或超时后退出 function waitFor(testFx, onReady, timeOutMillis) { var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 30000, // Default Max Timout is 30s start = new Date().getTime(), condition = false, interval = setInterval(function() { if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) { // If not time-out yet and condition not yet fulfilled condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); // defensive code } else { if(!condition) { // If condition still not fulfilled (timeout but condition is 'false') console.log("'waitFor()' timeout"); phantom.exit(1); } else { // Condition fulfilled (timeout and/or condition is 'true') console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms."); typeof(onReady) === "string" ? eval(onReady) : onReady(); // Do what it's supposed to do once the condition is fulfilled clearInterval(interval); // Stop this interval } } }, 1000); // repeat check every 1s }; //方法:添加单击事件 function click(el){ var ev = document.createEvent("MouseEvent"); ev.initMouseEvent( "click", true /* bubble */, true /* cancelable */, window, null, 0, 0, 0, 0, /* coordinates */ false, false, false, false, /* modifier keys */ 0 /*left*/, null ); el.dispatchEvent(ev); } //创建一个webpage var page = require('webpage').create(); //设置页面大小 page.viewportSize = { width: 480, height: 800 }; //设置代理:必须,否则会被server识别,并提醒使用服safari,chrome等最新版 page.settings.userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0"; //打开登录页 page.open('https://www.icloud.com/', function (s) { setTimeout(function() { console.log(" ======================================================== "); //jump to iframe page.switchToChildFrame(0); var title = page.evaluate(function(s) { return document.querySelectorAll(s)[0].innerHTML; }, 'h1'); console.log("========================get h1 :" + title); //打印log //input username by keyboard event var title = page.evaluate(function(s) { // 给用户名输入框添加focus事件及赋值。无focus事件则登录的小箭头图标无法点击 document.querySelectorAll(s)[0].value = 'royn.xxxx@icloud.co'; document.querySelectorAll(s)[0].focus(); return document.querySelectorAll(s)[0].placeholder; }, 'input[type=email]'); console.log("========================get username :" + title); //打印log //添加keypress事件,输入用户名最后一个字母:实践证明没有keypress事件,就算添加了focus事件且value正确,小箭头图标亦无法点击 page.sendEvent('keypress', 'm'); //截屏:查看用户名是否正确输入 page.render('inputUserName.png'); //input password :步骤和输入用户名相同 var title = page.evaluate(function(s) { document.querySelectorAll(s)[0].value = 'Love)106'; document.querySelectorAll(s)[0].focus(); return document.querySelectorAll(s)[0].placeholder; }, 'input[type=password]'); page.sendEvent('keypress', '9'); //截屏:查看密码是否输入正确 page.render('inputPassWord.png'); //添加回测登录事件:实际上即使登录的小箭头图标可以单击(颜色从灰变黑),phantomjs仍无法找到其dom节点添加单击事件,好在可以回车登录。 page.sendEvent('keypress', page.event.key.Enter); //wait to see login result setTimeout(function(){ //截屏:查看是否成功登录(setTimeout等了16s,这里假定登录成功且页面加载完了) page.render('successLogin.png'); //登录成功后单击“邮箱”图标,转到邮箱页面 var title = page.evaluate(function(s) { document.querySelector(s).click(); return document.querySelector(s).innerHTML; }, 'a[href="https://www.icloud.com/#mail"]'); console.log("========================get mail png html :" + title); waitFor(function() { //循环等待,直到邮箱页面加载成功或50s超时 var time = new Date().getTime(); //每一秒截屏一次,查看登录页面是否加载完毕 page.render(time + 'mailpagefinished.png'); return page.evaluate(function(s) { return document.querySelector(s).is(":visible"); }, 'iframe[name=mail]'); }, function() { console.log("The sign-in dialog should be visible now."); page.render('mailPageLoadingFinished.png'); phantom.exit(); }, 50000); //waitFor方法最长等待50s加载mail页,直到结束 },16000); //setTimeout:加载登录成功页结束 }, 15000); //setTimeout:加载登录首页结束 }); page.onConsoleMessage = function(msg) { console.log('Page title is ' + msg); }; page.onResourceError = function(resourceError) { console.error(resourceError.url + ': ' + resourceError.errorString); }; page.onResourceReceived = function(response) { console.log('= onResourceReceived()' ); console.log(' id: ' + response.id + ', stage: "' + response.stage + '", response: ' + JSON.stringify(response)); }; page.onLoadStarted = function() { console.log("currentFrameName(): "+page.currentFrameName()); console.log("childFramesCount(): "+page.childFramesCount()); onsole.log("childFramesName(): "+page.childFramesName()); console.log('= onLoadStarted()'); var currentUrl = page.evaluate(function() { return window.location.href; }); console.log(' leaving url: ' + currentUrl); }; page.onLoadFinished = function(status) { page.render('onLoadFinished.png'); }; page.onNavigationRequested = function(url, type, willNavigate, main) { console.log('= onNavigationRequested'); console.log(' destination_url: ' + url); console.log(' type (cause): ' + type); console.log(' will navigate: ' + willNavigate); console.log(' from page\'s main frame: ' + main); console.log("currentFrameName(): "+page.currentFrameName()); console.log("childFramesCount(): "+page.childFramesCount()); console.log("childFramesName(): "+page.childFramesName()); }; page.onResourceError = function(resourceError) { console.log('= onResourceError()'); console.log(' - unable to load url: "' + resourceError.url + '"'); console.log(' - error code: ' + resourceError.errorCode + ', description: ' + resourceError.errorString ); }; page.onError = function(msg, trace) { console.log('= onError()'); var msgStack = [' ERROR: ' + msg]; if (trace) { msgStack.push(' TRACE:'); trace.forEach(function(t) { msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : '')); }); } console.log(msgStack.join('\n')); };
4 phantomjs执行命令(linux)
4.1 以上代码存为一个js文件,如:/home//phantomjsfile/icloudCrawler.js
4.2 新建文件夹存储cookie,如:/home/phantomjsfile/cookies
4.3 执行phantomjs语句:
phantomjs --cookies-file=/home/phantomjsfile/cookies --debug=yes --ignore-ssl-errors=true --web-security=no --ssl-protocol=any /home/phantomjsfile/icloudCrawler.js
--debug : 会输出debug信息
--ignore-ssl-errors :忽视加密的ssl连接错误
--web-security :好象是忽略加密传输之类的,不加会请求失败
希望能对你有所帮助.
结束!!
相关文章推荐
- 十进制与二进制,八进制,十六进制的转换
- myBatis中OGNL
- delphi程序全屏显示无标题栏覆盖整个屏幕
- iOS开发系列--Swift 3.0
- 分布式事务
- [数据结构]Graph之拓扑排序BFS&DFS实现
- 浅谈Android的屏幕适配问题
- mysql两阶段提交
- Android 显示/隐藏 应用图标
- android产品研发(十二)-->App长连接实现
- Delphi7 实现窗体全屏方法
- msyql判断记录是否存在的三种方法
- 单调递增最长子序列
- 环回接口
- myBatis使用步骤
- webview被植入广告的的屏蔽方案
- 可以在线预览了
- Linux面试题
- 'XCTest/XCTest.h' file not found
- 滚动条下拉时 table 的thead 固定在网页固定在顶部不动