苹果icloud邮箱抓取

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 function waitFor(testFx, onReady, timeOutMillis) {
  3     var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 30000, // Default Max Timout is 30s
  4         start = new Date().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 function click(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 = ‘[email protected]‘;
 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           return document.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 = new Date().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     return window.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 :好象是忽略加密传输之类的,不加会请求失败

希望能对你有所帮助.

结束!!

时间: 2024-10-02 20:47:56

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

java邮箱抓取器

一.创建用户 1.利用IO创建目录和用户储存文件 2.利用json把用户账号密码传进去 二.登录用户 1.(1)利用JSON解析account.json读取出其中的账号密码 (2)利用的到的账号密码登录 2.如果没找到 5分钟再找一次 三.抓取邮件 1.利用jsoup

邮箱抓取代码

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Image; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.eve

java中使用 正则 抓取邮箱

我们来抓取豆瓣网的邮箱吧!把这个页面的所有邮箱都抓取下来 如https://www.douban.com/group/topic/8845032/: 代码如下: package cn.zhangzong.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnectio

通过WebClient类来发起请求并下载html 抓取邮箱 图片

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Text.RegularExpressions; using System.IO; namespace 通过WebClient类来发起请求并下载html 抓取邮箱 图片 { class Program { static void Main(string[] args

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

现实生活中咱们常常在浏览网页时看到自己需要的信息,但由于信息过于庞大而又不能逐个保存下来. 接下来,咱们就以获取邮箱地址为例,使用java语言抓取网页中的邮箱地址 实现思路如下: 1.使用Java.net.URL对象,绑定网络上某一个网页的地址 2.通过java.net.URL对象的openConnection()方法获得一个URLConnection对象 3.通过URLConnection对象的getInputStream()方法获得该网络文件的输入流对象InputStream 4.循环读取流

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

注:本程序可能非常适合那些做百度贴吧营销的朋友. 去逛百度贴吧的时候,经常会看到楼主分享一些资源,要求留下邮箱,楼主才给发. 对于一个热门的帖子,留下的邮箱数量是非常多的,楼主需要一个一个的去复制那些回复的邮箱,然后再粘贴发送邮件,不是被折磨死就是被累死.无聊至极写了一个抓取百度贴吧邮箱数据的程序,需要的拿走. 程序实现了一键抓取帖子全部邮箱和分页抓取邮箱两个功能,界面懒得做了,效果如下: 老规矩,直接贴源码 <?php $url2=""; $page="";

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

原文出自: http://outofmemory.cn/code-snippet/36020/php-how-zhuaqu-wangye-youxiangdizhi-code php如何抓取网页中邮箱地址,下面我就给大家分享一个用php抓取网页中电子邮箱的实例. 原文来自: www.pc100.net <?php /** desc:采集网页中的邮箱的代码 link:www.pc100.net date:2013/2/24 */ $url='http://www.pc100.net'; //要采集

winform网页抓取邮箱单发群发并有附件

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; using System.Net.Mail; using System.Net; u

抓取邮箱及资源

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using System.Net; u