5

から値を取得したいと思いhttps://play.google.com/store/account*ます。これにより、ユーザーページが出力されます。例:
/store/account?start=0&num=40、その後/store/account?start=40&num=40、など。

にアクセスしたときにhttps://play.google.com/apps、Greasemonkey にページの値を合計して、/store/accountそのページに最終的な値を表示してもらいたいと思います。

以下にリストされているコードは、ページから必要な値を合計でき/store/accountます。ただし、2 番目の URL に使用されるスクリプトにコードを挿入したいので、同じページに追加できます。

// ==UserScript==
// @name        Google Play 
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @grant       GM_setValue   
// @grant       GM_getValue  
// ==/UserScript==

var startParam      = location.search.match (/\bstart=(\d+)/i);
    if (startParam) {
        var totalPrice  = 0;
        var startNum    = parseInt (startParam[1], 10);
        if (startNum    === 0) {
            GM_setValue ("TotalPrice", "0");
        }
        else {
            totalPrice  = parseFloat (GM_getValue ("TotalPrice", 0) );
        }

        $("#tab-body-account .rap-link").each( function () {
            var price   = $(this).attr ("data-docprice").replace (/[^\d\.]/g, "");
            if (price) {
                price   = parseFloat (price);
                if (typeof price === "number") {
                    totalPrice += price;
                }
            }
        } );
        //console.log ("totalPrice: ", totalPrice.toFixed(2) );

        $('.tabbed-panel-tab').before (
            '<div id="SumTotal">*Combined Value: $'+ totalPrice.toFixed(2) +'</div>'
        );

        GM_setValue ("TotalPrice", "" + totalPrice);

        if ( $(".snippet.snippet-tiny").length ) {
            startNum       += 40;
            var nextPage    = location.href.replace (
                /\bstart=\d+/i, "start=" + startNum
            );
            location.assign (nextPage);
        }
    }
4

1 に答える 1

9

マッシュアップのためにページ/サイトからデータを取得するための基本的な方法は次のとおりです。

  1. AJAX 経由のスクレイピング:
    これはほとんどすべてのページで機能しますが、AJAX 経由で必要なコンテンツをロードするページでは機能しません。場合によっては、認証が必要なサイトやリファラーを制限しているサイトでも問題が発生することがあります. クロスドメイン スクリプティングを可能にするために、ほとんどの場合に
    使用します。GM_xmlhttpRequest()このアプローチについては、以下で詳しく説明します。

  2. でリソース ページをロードする<iframe>:
    このアプローチは AJAX 化されたページで機能し、ユーザーがサインインの問題を手動で処理できるようにコーディングできます。しかし、これは、より遅く、より多くのリソースを消費し、コーディングがより複雑になります。

    この質問の詳細には必要ないように思われるので、「応答を返す前にページがレンダリングされるのを待つ AJAX get-request を取得する方法は?」を参照してください。この技術の詳細については。

  3. API がある場合は、サイトの API を使用します。
    残念ながら、ほとんどのサイトには API がないため、これはおそらく選択肢ではありませんが、API が提供されていないことを確認する価値があります。API が利用可能な場合、通常は API が最適な方法です。このアプローチの詳細については、新しい検索/質問をしてください。

  4. サイトの AJAX 呼び出しを模倣して、必要な種類の情報を呼び出す場合:
    このオプションもほとんどのサイトには適用できませんが、適切な場合にはクリーンで効率的な手法になります。このアプローチの詳細については、新しい検索/質問をしてください。


クロスドメイン対応の AJAX を介して一連の Web ページから値を取得する:

ページをロードするために使用GM_xmlhttpRequest()し、HTML を処理するために jQuery を使用します。の関数を
使用して次のページを呼び出します。必要に応じて、同期 AJAX 呼び出しを使用しないでください。GM_xmlhttpRequest()onload

元のスクリプトのコア ロジックは関数内に移動しますがonload、Greasemonkey の実行間で値を記憶する必要がなくなります。

これは完全な Greasemonkey スクリプトで、いくつかのステータスとエラー レポートがスローされます。

// ==UserScript==
// @name        _Total-value mashup
// @include     https://play.google.com/apps*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @grant       GM_addStyle
// @grant       GM_xmlhttpRequest
// ==/UserScript==

var startNum        = 0;
var totalValue      = 0;

//--- Scrape the first account-page for item values:
$("body").prepend (
    '<div id="gm_statusBar">Fetching total value, please wait...</div>'
);
scrapeAccountPage ();

function scrapeAccountPage () {
    var accntPage   = 'https://play.google.com/store/account?start=0&num=40';
    accntPage       = accntPage.replace (/start=\d+/i, "start=" + startNum);

    $("#gm_statusBar").append (
        '<span class="gmStatStart">Fetching page ' + accntPage + '...</span>'
    );

    GM_xmlhttpRequest ( {
        method:     'GET',
        url:        accntPage,
        //--- getTotalValuesFromPage() also gets the next page, as appropriate.
        onload:     getTotalValuesFromPage,
        onabort:    reportAJAX_Error,
        onerror:    reportAJAX_Error,
        ontimeout:  reportAJAX_Error
    } );
}

function getTotalValuesFromPage (respObject) {
    if (respObject.status != 200  &&  respObject.status != 304) {
        reportAJAX_Error (respObject);
        return;
    }

    $("#gm_statusBar").append ('<span class="gmStatFinish">done.</span>');

    var respDoc     = $(respObject.responseText);
    var targetElems = respDoc.find ("#tab-body-account .rap-link");

    targetElems.each ( function () {
        var itmVal  = $(this).attr ("data-docprice").replace (/[^\d\.]/g, "");
        if (itmVal) {
            itmVal   = parseFloat (itmVal);
            if (typeof itmVal === "number") {
                totalValue += itmVal;
            }
        }
    } );
    console.log ("totalValue: ", totalValue.toFixed(2) );

    if ( respDoc.find (".snippet.snippet-tiny").length ) {
        startNum       += 40;
        //--- Scrape the next page.
        scrapeAccountPage ();
    }
    else {
        //--- All done!  report the total.
        $("#gm_statusBar").empty ().append (
            'Combined Value: $' + totalValue.toFixed(2)
        );
    }
}

function reportAJAX_Error (respObject) {
    $("#gm_statusBar").append (
        '<span class="gmStatError">Error ' + respObject.status + '! &nbsp; '
        + '"' + respObject.statusText + '" &nbsp; &nbsp;'
        + 'Total value, so far, was: ' + totalValue
        + '</span>'
    );
}

//--- Make it look "purty".
GM_addStyle ( multilineStr ( function () {/*!
    #gm_statusBar {
        margin:         0;
        padding:        1.2ex;
        font-family:    trebuchet ms,arial,sans-serif;
        font-size:      18px;
        border:         3px double gray;
        border-radius:  1ex;
        box-shadow:     1ex 1ex 1ex gray;
        color:          black;
        background:     lightgoldenrodyellow;
    }
    #gm_statusBar .gmStatStart {
        font-size:      0.5em;
        margin-left:    3em;
    }
    #gm_statusBar .gmStatFinish {
        font-size:      0.5em;
        background:     lime;
    }
    #gm_statusBar .gmStatError {
        background:     red;
        white-space:    nowrap;
    }
*/} ) );

function multilineStr (dummyFunc) {
    var str = dummyFunc.toString ();
    str     = str.replace (/^[^\/]+\/\*!?/, '') // Strip function() { /*!
            .replace (/\s*\*\/\s*\}\s*$/, '')   // Strip */ }
            .replace (/\/\/.+$/gm, '') // Double-slash comments wreck CSS. Strip them.
            ;
    return str;
}



重要:@include、、@excludeおよび/またはディレクティブを 忘れないで@matchください。スクリプトがすべてのページと iframe で実行されるわけではありません。

于 2012-11-12T05:26:39.977 に答える