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

1 //方法:循环等待,直到方法执行完或超时后退出
2 functionwaitFor(testFx, onReady, timeOutMillis) {3     var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 30000, //Default Max Timout is 30s
4         start = newDate().getTime(),5         condition = false,6         interval = setInterval(function() {7             if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {8                 //If not time-out yet and condition not yet fulfilled
9                 condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //defensive code
10             } else{11                 if(!condition) {12                     //If condition still not fulfilled (timeout but condition is 'false')
13                     console.log("'waitFor()' timeout");14                     phantom.exit(1);15                 } else{16                     //Condition fulfilled (timeout and/or condition is 'true')
17                     console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");18                     typeof(onReady) === "string" ? eval(onReady) : onReady(); //Do what it's supposed to do once the condition is fulfilled
19                     clearInterval(interval); //Stop this interval
20 }21 }22         }, 1000); //repeat check every 1s
23 };24
25 //方法:添加单击事件
26 functionclick(el){27     var ev = document.createEvent("MouseEvent");28 ev.initMouseEvent(29         "click",30         true /*bubble*/, true /*cancelable*/,31         window, null,32         0, 0, 0, 0, /*coordinates*/
33         false, false, false, false, /*modifier keys*/
34         0 /*left*/, null
35 );36 el.dispatchEvent(ev);37 }38
39 //创建一个webpage
40 var page = require('webpage').create();41
42 //设置页面大小
43 page.viewportSize ={44   width: 480,45   height: 800
46 };47
48 //设置代理:必须,否则会被server识别,并提醒使用服safari,chrome等最新版
49 page.settings.userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0";50
51 //打开登录页
52 page.open('https://www.icloud.com/', function(s) {53     setTimeout(function() {54       console.log(" ======================================================== ");55       //jump to iframe
56       page.switchToChildFrame(0);57       var title = page.evaluate(function(s) {58         return document.querySelectorAll(s)[0].innerHTML;59       }, 'h1');60       console.log("========================get h1 :" + title); //打印log
61
62       //input username by keyboard event
63       var title = page.evaluate(function(s) {64         //给用户名输入框添加focus事件及赋值。无focus事件则登录的小箭头图标无法点击
65         document.querySelectorAll(s)[0].value = 'royn.xxxx@icloud.co';66         document.querySelectorAll(s)[0].focus();67         return document.querySelectorAll(s)[0].placeholder;68       }, 'input[type=email]');69       console.log("========================get username :" + title); //打印log
70       //添加keypress事件,输入用户名最后一个字母:实践证明没有keypress事件,就算添加了focus事件且value正确,小箭头图标亦无法点击
71       page.sendEvent('keypress', 'm');72       //截屏:查看用户名是否正确输入
73       page.render('inputUserName.png');74
75       //input password :步骤和输入用户名相同
76       var title = page.evaluate(function(s) {77         document.querySelectorAll(s)[0].value = 'Love)106';78         document.querySelectorAll(s)[0].focus();79         return document.querySelectorAll(s)[0].placeholder;80       }, 'input[type=password]');81       page.sendEvent('keypress', '9');82       //截屏:查看密码是否输入正确
83       page.render('inputPassWord.png');84
85       //添加回测登录事件:实际上即使登录的小箭头图标可以单击(颜色从灰变黑),phantomjs仍无法找到其dom节点添加单击事件,好在可以回车登录。
86       page.sendEvent('keypress', page.event.key.Enter);87
88       //wait to see login result
89       setTimeout(function(){90         //截屏:查看是否成功登录(setTimeout等了16s,这里假定登录成功且页面加载完了)
91         page.render('successLogin.png');92         //登录成功后单击“邮箱”图标,转到邮箱页面
93         var title = page.evaluate(function(s) {94 document.querySelector(s).click();95           returndocument.querySelector(s).innerHTML;96         }, 'a[href="https://www.icloud.com/#mail"]');97         console.log("========================get mail png html :" +title);98
99         waitFor(function() {100           //循环等待,直到邮箱页面加载成功或50s超时
101           var time = newDate().getTime();102           //每一秒截屏一次,查看登录页面是否加载完毕
103           page.render(time + 'mailpagefinished.png');104           return page.evaluate(function(s) {105             return document.querySelector(s).is(":visible");106           }, 'iframe[name=mail]');107         }, function() {108           console.log("The sign-in dialog should be visible now.");109           page.render('mailPageLoadingFinished.png');110 phantom.exit();111         }, 50000); //waitFor方法最长等待50s加载mail页,直到结束
112
113       },16000); //setTimeout:加载登录成功页结束
114
115     }, 15000); //setTimeout:加载登录首页结束
116 });117
118 page.onConsoleMessage = function(msg) {119   console.log('Page title is ' +msg);120 };121
122 page.onResourceError = function(resourceError) {123   console.error(resourceError.url + ': ' +resourceError.errorString);124 };125
126 page.onResourceReceived = function(response) {127   console.log('= onResourceReceived()');128   console.log('  id: ' + response.id + ', stage: "' + response.stage + '", response: ' +JSON.stringify(response));129 };130
131 page.onLoadStarted = function() {132     console.log("currentFrameName(): "+page.currentFrameName());133     console.log("childFramesCount(): "+page.childFramesCount());134     onsole.log("childFramesName(): "+page.childFramesName());135   console.log('= onLoadStarted()');136   var currentUrl = page.evaluate(function() {137     returnwindow.location.href;138 });139   console.log('  leaving url: ' +currentUrl);140 };141
142 page.onLoadFinished = function(status) {143   page.render('onLoadFinished.png');144 };145
146 page.onNavigationRequested = function(url, type, willNavigate, main) {147   console.log('= onNavigationRequested');148   console.log('  destination_url: ' +url);149   console.log('  type (cause): ' +type);150   console.log('  will navigate: ' +willNavigate);151   console.log('  from page\'s main frame: ' +main);152     console.log("currentFrameName(): "+page.currentFrameName());153     console.log("childFramesCount(): "+page.childFramesCount());154     console.log("childFramesName(): "+page.childFramesName());155 };156
157 page.onResourceError = function(resourceError) {158   console.log('= onResourceError()');159   console.log('  - unable to load url: "' + resourceError.url + '"');160   console.log('  - error code: ' + resourceError.errorCode + ', description: ' +resourceError.errorString );161 };162
163 page.onError = function(msg, trace) {164   console.log('= onError()');165   var msgStack = ['  ERROR: ' +msg];166   if(trace) {167     msgStack.push('  TRACE:');168     trace.forEach(function(t) {169       msgStack.push('    -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));170 });171 }172   console.log(msgStack.join('\n'));173 };

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 :好象是忽略加密传输之类的,不加会请求失败

希望能对你有所帮助.

结束!!

转载于:https://www.cnblogs.com/McQueen1987/p/5594420.html

苹果icloud邮箱抓取相关推荐

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

    刚刚学完Socket,迫不及待的做了这个网页邮箱抓取~~~ 自己以前做过微商,而且还掏钱买过抓取网络邮箱的软件~现在O(∩_∩)O哈哈~我自己做~当然啦,没有别人做得好~只是功能还是差不多啦~ 给一个 ...

  2. python爬取百度贴吧中的所有邮箱_使用 Python 编写多线程爬虫抓取百度贴吧邮箱与手机号...

    原标题:使用 Python 编写多线程爬虫抓取百度贴吧邮箱与手机号 不知道大家过年都是怎么过的,反正栏主是在家睡了一天,醒来的时候登QQ发现有人找我要一份贴吧爬虫的源代码,想起之前练手的时候写过一个抓 ...

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

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

  4. python最简单的爬取邮箱地址_python简单爬虫,抓取邮箱

    最近,老师给了一个练习是,实现一个爬虫,就爬大概100个网页,匹配出邮箱. 于是,我花了几天时间,熟悉熟悉了python,就有了下面这个超级简单的爬虫程序.各种毛病...... 这里先说明一下,pyt ...

  5. .NET Core 实现定时抓取博客园首页文章信息并发送到邮箱

    前言 大家好,我是晓晨.许久没有更新博客了,今天给大家带来一篇干货型文章,一个每隔5分钟抓取博客园首页文章信息并在第二天的上午9点发送到你的邮箱的小工具.比如我在2018年2月14日,9点来到公司我就 ...

  6. java取邮箱前缀_java抓取网页或文件中的邮箱号码

    java抓取网页或文件中的邮箱号码 发布时间:2020-10-18 08:58:32 来源:脚本之家 阅读:69 作者:java大渣渣 本文实例为大家分享了java抓取邮箱号码的具体代码,供大家参考, ...

  7. python实现抓取网页上的内容并发送到邮箱

    要达到的目的: 从特定网页中抓取信息,排版后发送到邮箱中 关键点: 下载网页,从网页里抓取出需要的信息 HTML排版 发送到指定邮箱 实现: 1.python下载网页 直接用库函数就可以实现 from ...

  8. 一个用php抓取网页中电子邮箱的实例

    原文出自: http://outofmemory.cn/code-snippet/36020/php-how-zhuaqu-wangye-youxiangdizhi-code php如何抓取网页中邮箱 ...

  9. b站视频详情数据抓取,自动打包并发送到指定邮箱(单个或者群发)

    BiLiBiLi Time: 2020年11月6日19:44:58 Author: Yblackd BiLiBiLi BiLiBiLi 介绍 软件架构 安装教程 使用说明 源码下载 BiLiBiLi ...

最新文章

  1. softmax(a,axis=0)的用法理解 总结
  2. 上传ML模型,一键可视化,终于能看懂神经网络到底在干啥了
  3. GWT更改元素样式属性
  4. MyBatis使增删改不刷新二级缓存
  5. 关于Objective-C 对象release操作的一个小问题探讨
  6. SpringBoot实战(九)之Validator
  7. 锦囊5-斐波那契数列
  8. QT5软件开发入门到项目实战PDF(配完整示例代码)(持续更新)
  9. 分布式一致性—Paxos算法
  10. 计算机考研各个学校专业课,【择校必看】十三所计算机专业课只考数据结构的985院校!...
  11. 联想电脑管家不显示开机时间_联想电脑怎么设置显示开机时间
  12. Install Mysql MMM On Redhat6.3
  13. 真心推荐8个高质量Java学习网站,一起从入门到精通java语言,大厂java面试真题分享,建议码住!...
  14. 墨画子卿第四章第6节:卷轴
  15. root 红米note5_红米Note5 root教程_红米Note5卡刷root包来获取root权限
  16. 音频算法检测发言者方位
  17. 编程之美之数独求解器的C++实现方法
  18. 做设计师要用到的工具软件
  19. 员工怎样跟老板谈加薪 7个技巧让你成功加薪
  20. 浅析 vSAN 磁盘组架构和缓存盘的“消亡”

热门文章

  1. Hibernate中ManyToOne删除Many的一方出现 deleted object would be re-saved by cascade
  2. 【机械革命】蛟龙17X笔记本的使用笔记
  3. 把数据库中的数据写出到excel表格中
  4. 如何串联两个路由器(建议用第二种方法)
  5. MEG预处理-Brainstorm
  6. UDS刷写结束时发送的11服务是否需要回复?
  7. 麦子学院-Web前端开发工程师系列培训教程
  8. Axure可视化动态数据图表6合1元件库
  9. license.lic
  10. 日志管理第四部分:如何防止黑客通过端口扫描进行网络攻击?