【问题标题】:Download flurry event log using curl使用 curl 下载 Flurry 事件日志
【发布时间】:2015-02-19 10:04:32
【问题描述】:

我开始使用 Flurry Analytics,发现它的分析工具不足且速度太慢。 3 个步骤的简单漏斗处理了 3 天,而对于 100,000 行的表,使用 3 个左连接的查询通常需要 0,001 秒。

Flurry 允许在 Event Logs 页面上以 csv 格式下载原始事件数据,因此我决定导入所有事件并在家里对其进行分析。

Flurry 只允许下载 100,000 条记录,他们建议经常下载以适应此限制。他们有原始事件下载 API,但由于某种原因放弃了它。因此,唯一的方法是转到事件日志页面并手动下载事件数据。但正如你可以想象的那样,这很烦人。

所以我决定在 php 中使用 curl 来获取这些数据。我已经复制了 GET HTTP 请求以下载带有标头的链接并获取了数据。 但整个魔法都在会话/cookies 中,我可以从现有会话中复制。因此,要使 curl 查询成功,我必须:

  1. 在浏览器中访问 Flurry 网站并登录
  2. 进入事件日志页面,选择时间范围参数并点击下载
  3. 在嗅探器中复制请求标头
  4. 将它们粘贴到我的 php 代码中
  5. 从现在开始,我可以在 php 中进行此查询,直到会话 cookie 过期

我不确定,但假设 cookie 将在第二天过期,所以整个努力都是徒劳的。

据我了解,我应该尝试使用 curl 登录登录,并保持此连接执行 GET 以下载数据。然而,即使复制整个 POST 登录请求正文,我也无法登录 - 尽管应该 302 重定向到,但它使用相同的登录页面回答 https://dev.flurry.com/fullPageTakeover.do?originalTarget=&isFirstPostLogin=true&defaultTarget=%2Fhome.do

看起来 Flurry 以某种方式受到了这种卷曲阅读的保护。或者也许有人成功了?

代码如下:

    $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问题!

【问题讨论】:

  • 您在登录时遇到问题吗?您发布的链接仍然需要您输入电子邮件和密码。请向我们展示您使用 cURL 执行此登录请求的代码。
  • @silkfire 我添加了一种测试代码变体。理论上一切正常,但flurry返回相同的登录页面。
  • 我认为您的 cURL 代码没有任何问题。从外观上看,它应该可以工作。不幸的是,如果无法访问帐户,这很难进行测试:(
  • 注册需要几分钟时间:dev.flurry.com/secure/signup.do。过程涉及电子邮件,所以每个人都应该注册自己。顺便说一句,Flurry 是免费的。
  • 如果我注册,我从哪里获得游戏 ID?

标签: php curl flurry


【解决方案1】:

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;

【讨论】:

  • 谢谢,太棒了!我也设置了 CURLOPT_COOKIEFILE 和 CURLOPT_FILE 并且 GET 到 dev.flurry.com/eventsLogCsv.do 成功了!
  • @Tertium 将CURLOPT_COOKIEFILE 设置为null 就足够了。它将允许您的 cURL 句柄存储 cookie,但它们仅保存在内存中,不会弄乱您的项目文件夹。
  • 谢谢,我只是想看看那里有什么。
  • 嗨 Silkfire 和 Tertium。我对 PHP 和这些类型的脚本不是很熟悉。我想知道你们是否可以根据您的代码提供一个完整的解决方案来登录 Flurry 并获取所有日志事件。目前我不明白这两个脚本是如何做到的。我希望有一个 for 循环或其他东西。如果你有时间,你能帮忙吗?谢谢。
  • 现在谁在乎,flurry 数据很糟糕,很多事件都被省略了,甚至我自己的日志也能更好地处理它们。
猜你喜欢
  • 2013-03-14
  • 1970-01-01
  • 2014-04-06
  • 2016-05-02
  • 2012-09-03
  • 2013-01-11
  • 1970-01-01
  • 2012-05-25
  • 1970-01-01
相关资源
最近更新 更多