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 代码实现

 //方法:循环等待,直到方法执行完或超时后退出
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 :好象是忽略加密传输之类的,不加会请求失败

希望能对你有所帮助.

结束!!

苹果icloud邮箱抓取的更多相关文章

  1. Java---网络蜘蛛-网页邮箱抓取器~源码

    刚刚学完Socket,迫不及待的做了这个网页邮箱抓取~~~ 现在有越来越多的人热衷于做网络爬虫(网络蜘蛛),也有越来越多的地方需要网络爬虫,比如搜索引擎.资讯采集.舆情监测等等,诸如此类.网络爬虫涉及 ...

  2. java中使用 正则 抓取邮箱

    我们来抓取豆瓣网的邮箱吧!把这个页面的所有邮箱都抓取下来 如https://www.douban.com/group/topic/8845032/: 代码如下: package cn.zhangzon ...

  3. 如何使用JAVA语言抓取某个网页中的邮箱地址

    现实生活中咱们常常在浏览网页时看到自己需要的信息,但由于信息过于庞大而又不能逐个保存下来. 接下来,咱们就以获取邮箱地址为例,使用java语言抓取网页中的邮箱地址 实现思路如下: 1.使用Java.n ...

  4. java抓取网页或者文件的邮箱号码

    抓文件的 package reg; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.i ...

  5. 用PHP抓取百度贴吧邮箱数据

    注:本程序可能非常适合那些做百度贴吧营销的朋友. 去逛百度贴吧的时候,经常会看到楼主分享一些资源,要求留下邮箱,楼主才给发. 对于一个热门的帖子,留下的邮箱数量是非常多的,楼主需要一个一个的去复制那些 ...

  6. 在Mac Os(苹果)上用手机抓包软件Charles抓取微信小程序中的高清无水印视频

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_118 手机抓包是一名测试工程师常备的技能,比如我想查看一个接口请求的参数.返回值,还有移动设备上的http请求.https请求,这 ...

  7. 网络爬虫: 从allitebooks.com抓取书籍信息并从amazon.com抓取价格(1): 基础知识Beautiful Soup

    开始学习网络数据挖掘方面的知识,首先从Beautiful Soup入手(Beautiful Soup是一个Python库,功能是从HTML和XML中解析数据),打算以三篇博文纪录学习Beautiful ...

  8. ios 抓取真机的网络包

    一直被如何从真机上抓包所困扰!今天偶然看到了最简单有效的方法!分享一下: 原地址链接 http://blog.csdn.net/phunxm/article/details/38590561 通过 R ...

  9. iOS开发——网络实用技术OC篇&网络爬虫-使用青花瓷抓取网络数据

    网络爬虫-使用青花瓷抓取网络数据 由于最近在研究网络爬虫相关技术,刚好看到一篇的的搬了过来! 望谅解..... 写本文的契机主要是前段时间有次用青花瓷抓包有一步忘了,在网上查了半天也没找到写的完整的教 ...

随机推荐

  1. hdu 3449 (有依赖的01背包)

    依赖背包 事实上,这是一种树形DP,其特点是每个父节点都需要对它的各个儿子的属性进行一次DP以求得自己的相关属性. fj打算去买一些东西,在那之前,他需要一些盒子去装他打算要买的不同的物品.每一个盒子 ...

  2. 浅谈javascript中的call()和apply()方法

    话说在js中,每个函数都包含两个非继承而来的放方法,apply()和call(),使得我们能在特定的作用域中调用函数. 官方定义: 语法:       fun.call(thisArg[, arg1[ ...

  3. openSUSE 安装

    https://lug.ustc.edu.cn/sites/opensuse-guide/installation.php 开始 1. 简介2. 改用 GNU/Linux3. 获取 openSUSE4 ...

  4. 【高德地图API】那些年我们一起开发的APP—即LBS应用模式分享

    原文:[高德地图API]那些年我们一起开发的APP—即LBS应用模式分享 摘要:利用地图API都能做些什么应用呢?应用商店里所有的分类,都可以结合上LBS来丰富应用.除了传统的生活服务应用,还有新潮的 ...

  5. .net的自定义JS控件,运用了 面向对象的思想 封装 了 控件(.net自定义控件开发的第一天)

    大家好!我叫刘晶,很高兴你能看到我分享的文章!希望能对你有帮助! 首先我们来看下几个例子 ,就能看到 如何 自定义控件! 业务需求: 制作  一个   属于 自己的    按钮 对象    ,然后 像 ...

  6. poj3070--Fibonacci(矩阵的高速幂)

    Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9650   Accepted: 6856 Descrip ...

  7. 1.cocos2dx它Menu(CCMenuItemFont,CCMenuItemImage,CCMenuItemLabel,CCMenuItemSprite,CCMenuItemToggle)

     CCMenu 基本结构 CCMenu继承自CCLayer,本质是一个容器.须要被addChild到父类中去. CCMenuItem是菜单项,它有例如以下子类: CCMenuItemFont;CC ...

  8. 如何为你的初创应用App开发公司建立战略计划(商业战略竞争五力学)

    首先,什么是战略计划?战略计划可以定义为一个为了达到目标而需要执行的一系列动作步骤的计划. 根据当今全球第一战略权威,商业管理界公认的"竞争战略之父"Michael Porter著 ...

  9. java中Integer包装类的具体解说(java二进制操作,全部进制转换)

    程序猿都非常懒,你懂的! 今天为大家分享的是Integer这个包装类.在现实开发中,我们往往须要操作Integer,或者各种进制的转换等等.我今天就为大家具体解说一下Integer的使用吧.看代码: ...

  10. 深入理解JavaScript(1)

    才华横溢的Stoyan Stefanov,在他写的由O’Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会 ...