使用 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 查询成功,我必须:

  1. 在浏览器中转到 flurry 站点并登录
  2. 进入事件日志页面,选择时间范围参数并点击下载
  3. 在嗅探器
  4. 中复制请求headers
  5. 将它们粘贴到我的 php 代码中
  6. 从现在开始,我可以在 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;