使用 curl 下载 flurry 事件日志
Download flurry event log using curl
我开始使用 Flurry Analytics,发现它的分析工具不足且速度太慢。包含 3 个步骤的简单漏斗处理了 3 天,而通常使用 3 个左连接的查询在 table 上用 100,000 行花费 0,001 秒。
Flurry 允许在事件日志页面上以 csv 格式下载原始事件数据,因此我决定导入所有事件并在家进行分析。
Flurry 只允许下载 100,000 条记录,他们建议经常下载以符合此限制。他们下载了原始事件 API 但出于某种原因放弃了它。所以唯一的方法是转到事件日志页面并手动下载事件数据。但是正如您想象的那样,这非常烦人。
所以我决定在 php 中使用 curl 获取这些数据。我已经复制了 GET HTTP 请求以使用 headers 下载 link 并获取了数据。
但整个魔法都在 session/cookies 中,我可以从现有的 session 中复制它。所以要使 curl 查询成功,我必须:
- 在浏览器中转到 flurry 站点并登录
- 进入事件日志页面,选择时间范围参数并点击下载
- 在嗅探器
中复制请求headers
- 将它们粘贴到我的 php 代码中
- 从现在开始,我可以在 php 中进行此查询,直到 session cookie 过期
我不确定,但假设 cookie 将在第二天过期,所以所有这些努力都是无用的。
据我所知,我应该尝试 POST 使用 curl 登录,并保持此连接执行 GET 以下载数据。然而,即使复制整个 POST 登录请求 body 我也无法登录 - 尽管 302 应该重定向到
https://dev.flurry.com/fullPageTakeover.do?originalTarget=&isFirstPostLogin=true&defaultTarget=%2Fhome.do
Flurry 似乎以某种方式受到保护,不受此类卷曲读取的影响。或者也许有人body 成功了?
代码如下:
$cookie_file_path = "cookies.txt";
$LOGINURL = "https://dev.flurry.com/secure/login.do";
$MY_EMAIL ="my email";
$MY_PASS="password";
$MY_GAME_ID="gameid";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
curl_setopt ($ch, CURLOPT_REFERER, $LOGINURL);
curl_setopt($ch, CURLOPT_URL, $LOGINURL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "loginEmail=$MY_EMAIL&loginPassword=$MY_PASS&__checkbox_rememberMe=true&struts.token.name=struts.token&struts.token=7NB9NWLOYZ8SD8TWR8LGS63REVDI8SQS");
$result = curl_exec($ch);
$remotePageUrl = "https://dev.flurry.com/eventsLogCsv.do?projectID=$MY_GAME_ID&versionCut=versionsAll&intervalCut=7Days&stream=true&direction=1&offset=0";
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, $remotePageUrl);
$result = curl_exec($ch);
echo $result;
还尝试传递 cookie(就像从浏览器中传递的那样),但无济于事:
Cookie: _ga=GA1.2.100867533.1424333566; S0hZTkM0RFRXRjJNSlg2TVdXSEs_fit=1424333594147; fid=SG1162A8DEFC14B8428E7C2AFC71D3AEA00C1872F5; JSESSIONID=w34~mvbdvftm9x9dez9dg9b2pmhs; _map_zoomLevel=0;
_map_zoneId=0; __utmt=1; __utmt_~1=1; S0hZTkM0RFRXRjJNSlg2TVdXSEs_fs=eyJiYSI6MTQyNDMzNzkzMzU2OCwicGF1c2VUaW1lc3RhbXAiOjAsImJjIjotMSwiZXZlbnRDb3VudGVyIjowLCJwdXJjaGFzZUNvdW50ZXIiOjAsImVycm9yQ291bnRlciI6MCwidGltZWRFdmVudHMiOltdfQ==;
__utma=83277827.100867533.1424333566.1424333594.1424336847.2; __utmb=83277827.8.10.1424336847; __utmc=83277827; __utmz=83277827.1424333594.1.1.utmcsr=flurry.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utma=34058230.100867533.1424333566.1424333566.1424336847.2; __utmb=34058230.8.10.1424336847; __utmc=34058230; __utmz=34058230.1424333566.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _mkto_trk=id:802-TBR-126&token:_mch-flurry.com-1424333577360-64839; S0hZTkM0RFRXRjJNSlg2TVdXSEs_flp=1424338032448
感谢silkfire Flurry 问题已解决!
struts.token
是一个 CRSF 令牌,它绑定到您的会话并在每次页面加载时重新生成。但是在您的代码中,它是静态的。您需要在您的第一个 cURL 请求之后获取它,然后将其注入您的 POST 数组以用于您的第二个请求。
此外,您必须登录的页面是 /loginAction.do
而不是 /login.do
。
这是我成功登录 Flurry 的方式:
$post = [
'loginEmail' => 'E-MAIL',
'loginPassword' => 'PASSWORD',
'struts.token.name' => 'struts.token'
];
$ch = curl_init('https://dev.flurry.com/secure/login.do');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_COOKIEFILE, null);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
libxml_use_internal_errors(true);
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadHTML(curl_exec($ch));
$xpath = new DOMXPath($dom);
$post['struts.token'] = $xpath->query('//input[@name="struts.token"]')->item(0)->getAttribute('value');
curl_setopt($ch, CURLOPT_URL, 'https://dev.flurry.com/secure/loginAction.do');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$data = curl_exec($ch);
echo $data;
我开始使用 Flurry Analytics,发现它的分析工具不足且速度太慢。包含 3 个步骤的简单漏斗处理了 3 天,而通常使用 3 个左连接的查询在 table 上用 100,000 行花费 0,001 秒。
Flurry 允许在事件日志页面上以 csv 格式下载原始事件数据,因此我决定导入所有事件并在家进行分析。
Flurry 只允许下载 100,000 条记录,他们建议经常下载以符合此限制。他们下载了原始事件 API 但出于某种原因放弃了它。所以唯一的方法是转到事件日志页面并手动下载事件数据。但是正如您想象的那样,这非常烦人。
所以我决定在 php 中使用 curl 获取这些数据。我已经复制了 GET HTTP 请求以使用 headers 下载 link 并获取了数据。 但整个魔法都在 session/cookies 中,我可以从现有的 session 中复制它。所以要使 curl 查询成功,我必须:
- 在浏览器中转到 flurry 站点并登录
- 进入事件日志页面,选择时间范围参数并点击下载
- 在嗅探器 中复制请求headers
- 将它们粘贴到我的 php 代码中
- 从现在开始,我可以在 php 中进行此查询,直到 session cookie 过期
我不确定,但假设 cookie 将在第二天过期,所以所有这些努力都是无用的。
据我所知,我应该尝试 POST 使用 curl 登录,并保持此连接执行 GET 以下载数据。然而,即使复制整个 POST 登录请求 body 我也无法登录 - 尽管 302 应该重定向到 https://dev.flurry.com/fullPageTakeover.do?originalTarget=&isFirstPostLogin=true&defaultTarget=%2Fhome.do
Flurry 似乎以某种方式受到保护,不受此类卷曲读取的影响。或者也许有人body 成功了?
代码如下:
$cookie_file_path = "cookies.txt";
$LOGINURL = "https://dev.flurry.com/secure/login.do";
$MY_EMAIL ="my email";
$MY_PASS="password";
$MY_GAME_ID="gameid";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt ($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
curl_setopt ($ch, CURLOPT_REFERER, $LOGINURL);
curl_setopt($ch, CURLOPT_URL, $LOGINURL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "loginEmail=$MY_EMAIL&loginPassword=$MY_PASS&__checkbox_rememberMe=true&struts.token.name=struts.token&struts.token=7NB9NWLOYZ8SD8TWR8LGS63REVDI8SQS");
$result = curl_exec($ch);
$remotePageUrl = "https://dev.flurry.com/eventsLogCsv.do?projectID=$MY_GAME_ID&versionCut=versionsAll&intervalCut=7Days&stream=true&direction=1&offset=0";
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, $remotePageUrl);
$result = curl_exec($ch);
echo $result;
还尝试传递 cookie(就像从浏览器中传递的那样),但无济于事:
Cookie: _ga=GA1.2.100867533.1424333566; S0hZTkM0RFRXRjJNSlg2TVdXSEs_fit=1424333594147; fid=SG1162A8DEFC14B8428E7C2AFC71D3AEA00C1872F5; JSESSIONID=w34~mvbdvftm9x9dez9dg9b2pmhs; _map_zoomLevel=0;
_map_zoneId=0; __utmt=1; __utmt_~1=1; S0hZTkM0RFRXRjJNSlg2TVdXSEs_fs=eyJiYSI6MTQyNDMzNzkzMzU2OCwicGF1c2VUaW1lc3RhbXAiOjAsImJjIjotMSwiZXZlbnRDb3VudGVyIjowLCJwdXJjaGFzZUNvdW50ZXIiOjAsImVycm9yQ291bnRlciI6MCwidGltZWRFdmVudHMiOltdfQ==;
__utma=83277827.100867533.1424333566.1424333594.1424336847.2; __utmb=83277827.8.10.1424336847; __utmc=83277827; __utmz=83277827.1424333594.1.1.utmcsr=flurry.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utma=34058230.100867533.1424333566.1424333566.1424336847.2; __utmb=34058230.8.10.1424336847; __utmc=34058230; __utmz=34058230.1424333566.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _mkto_trk=id:802-TBR-126&token:_mch-flurry.com-1424333577360-64839; S0hZTkM0RFRXRjJNSlg2TVdXSEs_flp=1424338032448
感谢silkfire Flurry 问题已解决!
struts.token
是一个 CRSF 令牌,它绑定到您的会话并在每次页面加载时重新生成。但是在您的代码中,它是静态的。您需要在您的第一个 cURL 请求之后获取它,然后将其注入您的 POST 数组以用于您的第二个请求。
此外,您必须登录的页面是 /loginAction.do
而不是 /login.do
。
这是我成功登录 Flurry 的方式:
$post = [
'loginEmail' => 'E-MAIL',
'loginPassword' => 'PASSWORD',
'struts.token.name' => 'struts.token'
];
$ch = curl_init('https://dev.flurry.com/secure/login.do');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_COOKIEFILE, null);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
libxml_use_internal_errors(true);
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadHTML(curl_exec($ch));
$xpath = new DOMXPath($dom);
$post['struts.token'] = $xpath->query('//input[@name="struts.token"]')->item(0)->getAttribute('value');
curl_setopt($ch, CURLOPT_URL, 'https://dev.flurry.com/secure/loginAction.do');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$data = curl_exec($ch);
echo $data;