← すべての記事

大規模な感情分析に向けた商品レビューの集約

レビューはJSレンダリング、ページネーション、サイト側の検証の背後に存在します。感情分析モデルへ有用なデータを供給するために、集約パイプラインに求められる要件を解説します。

課題

消費者向けブランドは、もはや単一のマーケットプレイスのレビューダッシュボードだけに頼ることはできません。同一のSKUであっても、Amazon、Walmart、Best Buy、さらにはTrustpilotやブランド独自のShopifyストアでそれぞれ異なるビュースコアが存在します。プロダクトチーム、感情分析モデル、CX運用キューがそのうちの1つしか参照していない場合、歪んだ情報をもとに判断を下すことになります。

これが日常的に発生するレビューの断片化問題です。レビュー自体は存在しますが、10通りの異なるログイン、10通りのレンダリングスタック、そして10通りのボット検知設定の背後に分散しています。感情分類器に毎週データを供給する(または主要商品の出品に悪質なレビューが投稿された際にアラートをトリガーする)には、すべての最新レビューを一元化する必要があります。

それらの集約は、データ処理の問題である前にレンダリングの問題です。そして大半のチームは、この前段階の難しさを過小評価しています。

難易度が高い理由

2026年のレビューページは、2018年のそれとは完全に異なります。重要な要素はすべて初期HTMLの描画以降に読み込まれます。

  • レビューリスト自体は、ブラウザがシェルを描画した後にJSON経由で取得されます。
  • より深いページ(「さらにレビューを表示」、ページネーション)では、セッションに適切なcookieを保持する必要があり、スクロール操作が求められることもよくあります。
  • 並べ替えフィルター(最新順、確認済み購入者のみなど)はrequestシグネチャを変更します。指定を誤ると、マーケットプレイスはデフォルトのビューを返し、同時に気付きにくいrate limitを適用します。
  • ページ全体がボット防御の背後に配置されており、User-Agentを検査する前に、requestの低レベルシグネチャ、headerの順序、およびタイミングが検証されます。

通常のHTTP requestで該当ページを取得すると、空のシェル(レビューも評価もない状態)が返されます。自前のheadlessブラウザで取得しようとすると、ブラウザの保守、送信元IPのローテーション、マーケットプレイスによるボット検知ルールの変更に伴う継続的なパッチ適用といったコストを抱え込むことになります。

解決策

有効なパターンは、単一のAPI endpointとして呼び出せるブラウザベースの取得です。レビューURLを渡すだけで、ページをレンダリングし、JavaScriptを実行し、レビューペイロードのハイドレーションを待機して、DOMを返します。セッション情報はresponseに含まれるため、次回のページネーション取得時に再利用できます。

FourAのBrowser productを使用すると、Pythonでは次のように実装できます。

import requests

def fetch_reviews(url, api_key, sticky_proxy=None):
    body = {
        "url": url,
        "unblocker": True,
    }
    if sticky_proxy:
        body["proxy"] = sticky_proxy

    r = requests.post(
        "https://api.foura.ai/api/browser",
        headers={"Authorization": f"Bearer {api_key}"},
        json=body,
        timeout=60,
    ).json()

    return {
        "status": r.get("status"),
        "html": r.get("body"),
        "cookies": r.get("cookies"),
        "sticky_proxy": r.get("proxy"),
        "defense_solved": r.get("defenseSolved"),
    }

レビューのスクレイピングでは、2つの詳細が重要になります。

第1に、多くのマーケットプレイスのレビューページが背後に配置しているワイヤーレベルの防御をunblocker: trueが処理します。これがない場合、レビューではなくチャレンジページが返されます。

第2に、返されるproxyの値は、レンダリングに成功したイグジットのbase36 IDです。同じ製品に対する次の呼び出しでこれを再度渡すことで、ページネーション側からは同一の訪問者として扱われます。そのため、1ページ目は正常に読み込まれるのに3ページ目で何も返されなくなる問題は、多くの場合セッションを固定(ピン留め)していたかどうかで決まります。

上位20件のレビューについて週次の最新スナップショットのみが必要な製品の場合は、スティッキーセッションをスキップし、呼び出しごとに独自のイグジットを選択させてください。セッションの固定は、深いページネーションが実際に重要となるSKU用に残しておきます。

期待できる結果

このパターンでレビュー集約を実行するチームは、次の基準で考える必要があります。

  • カバレッジ: 販売しているすべてのマーケットプレイスにおける全製品のレビューを、CX向けアラート用の日次からトレンド分析用の週次まで、ダウンストリームが必要とする任意の頻度で更新できます。
  • 深度: マーケットプレイスごとの各SKUについてレビューの最初の3から5ページを取得します。実行可能なシグナルが存在するのはこの領域です。感情分析の観点では、5ページを超えるロングテール部分はほとんどノイズとなります。
  • 鮮度: 新しいレビューは、月次のエクスポートが実行される2週間後ではなく、投稿されてから1日以内に感情分析パイプラインに取り込まれます。
  • コストの予測可能性: レンダリングされたフェッチ単位で課金されるため、予算はブラウザの保守に必要なチームの規模ではなく、対象とするSKUの数に応じてスケールします。

これらは非現実的な数値ではありません。レンダリング側の課題をチームの作業から切り離すことで得られる成果です。

完全なマーケットプレイス監視スタックと比較した場合、レビュー集約は感情分析に特化した関連分野と言えます。同じレンダリング基盤を利用し、異なるダウンストリームに対応します。

主なポイント

ブランドが確認するあらゆるダッシュボードは、最終的にはチャートに行き着きます。ただし、チャートはダウンストリームに過ぎません。アップストリーム側のコスト(大半のブランドがこれを適切に運用できない理由)はレンダリングフリートにあります。15のマーケットプレイス画面への到達性を維持し、スクレイピングを阻止するために構築された防御を回避し続けながら、エンジニア3人とproxy契約を抱え込まないコストで運用することです。

レンダリング側の課題がレビュー集約プロジェクトの障害になっているのであれば、その部分こそ外部化すべきです。感情分析モデル、ダッシュボード、アラート機能などは、最新のレビューが届き始めさえすれば、チームが短期間で構築できるパーツです。