> This page is for プラットフォーム, version レガシー.
> For other versions, use one of these documentation indexes:
> - V4 (default): https://next.developer.frame.io/platform/v4/llms.txt
> - V4 Experimental: https://next.developer.frame.io/platform/v4-experimental/llms.txt
> - レガシー: https://next.developer.frame.io/platform/v2/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# プロジェクトからのすべてのコメントの収集

## 概要
コメントスクレイパーは、プロジェクトに含まれているすべてのアセットを取得し、コメントをスクレイピングして .csv ファイルに出力します。この説明では次のリソースを使用します。
* [Python SDK](https://github.com/Frameio/python-frameio-client) -この SDK はページネーションを処理し、開発者トークン（ベアラー認証）で使用できるクライアントを設定します。
* [Python のコメントスクレイパー](https://github.com/Frameio/comment-scraper-python) -使用しているコードサンプルにはこちらからアクセスできます。

### Glitch で試す
Glitch はシンプルなツールで、独自のアプリケーションを設定し、それらを Glitch 側のサーバーを使用してテストおよび実行できます。Glitch に慣れていない場合は、[Glitch の使用](/other-tools/using-glitch)に関するガイドを参照してください。

サーバー上でコメントスクレイパーが動作することを確認する場合は、[Glitch](https://glitch.com) に用意した Flask アプリをご利用ください：[Python で記述した Frame.io コメントスクレイパー](https://glitch.com/~frameio-comment-scraper)。

### 必要なスコープ
このガイドを開始する前に、少なくとも次のスコープを含むトークンがあることを確認してください。

| スコープ| 理由|
|----------|----------|
| **プロジェクト：**読み取り| 厳密には必須ではありませんが、プロジェクトの `root_asset_id` をフェッチするために必要です。|
| **アセット：**読み取り| API 経由での `asset_ids` ナビゲーションに必要です。|
| **コメント：**読み取り| コメントそのものを取得するために必要です。|

### 1\.アプリを準備する
このガイドでは、[ファイルツリーの読み取り](/workflows-assets/reading-the-file-tree)と同様のパターンに従います。したがって、開始するには以下が必要です。
* クロール対象プロジェクトの `root_asset_id`
* [開発者トークン](/authentication/developer-tokens)

また、`FrameioClient` やいくつかの追加ヘルパーライブラリーを Python アプリに読み込むことになります。

**`Python`**

```python title="Python"
from frameioclient import FrameioClient
import requests, json, csv, itertools

ROOT_ASSET_ID = "<ROOT_ASSET_ID>"
TOKEN = "<DEV_TOKEN>"
```

### 2\.プロジェクトをクロールする
次に、すべてのアセットを再帰的に取得し、コメントを確認し、コメント付きのアセットをリストに保管する必要があります。それをもとに .csv ファイルを作成できます。

プロジェクトをクロールする際には、各アセットについて次のチェックを行う必要があります。
* アセットはファイルか？（`"_type": "file"`）
  * ファイルの場合、コメントはあるか？
    * **ある場合は、それらを取得してリストに追加します。**
* アセットはフォルダーか？（`"_type": "folder"`）
  * **フォルダーの場合は、その子に対して再帰処理を行います。**
* アセットはバージョンスタックか？（`"_type": "version_stack"`）
  * **バージョンスタックの場合は、すべての子を取得し、コメントを確認します。**

**`Python`**

```python title="Python"
def all_comments(client, asset_id, comment_list):
    files = client.get_asset_children(asset_id)

    for asset in files:
        if asset['type'] == "file":
            if asset['comment_count'] > 0:
                asset_parent_id = asset['parent_id']
                asset_name = asset['name']
                comments = client.get_comments(asset['id'])
                my_comment_list = [comment for comment in comments.results]
                for object in my_comment_list:
                    object.update({'parent_id':asset_parent_id})
                    object.update({'name':asset_name})
                comment_list.append(my_comment_list)

        if asset['type'] == "folder":
            if asset['item_count'] > 0:
                all_comments(client, asset['id'], comment_list)

        if asset['type'] == "version_stack":
            asset_name = asset['name']
            parent_id = asset['parent_id']
            vfiles = client.get_asset_children(asset['id'])

            for asset in vfiles.results:
                asset_name = asset['name']
                parent_id = asset['parent_id']
                if asset['type'] == "file":
                    if asset['comment_count'] > 0:
                        comments = client.get_comments(asset['id'])
                        my_comment_list = [comment for comment in comments.results]
                        for object in my_comment_list:
                            object.update({'parent_id':parent_id})
                            object.update({'name':asset_name})
                        comment_list.append(my_comment_list)

def get_all_project_comments(root_asset_id, token):
    comment_list = []
    client = FrameioClient(token)

    all_comments(client, root_asset_id, comment_list)

    return comment_list
```

<Info title="ページネーションをお忘れなく">
上記の例ではページネーションは無視されます -- ただし、大きなコレクションをナビゲートするときは無視しないでください。詳細については、[基本概念](/getting-started/key-concepts#pagination)ガイドを参照してください。
</Info>

### 3\.コメントリストをフラット化する
クロール段階で処理しないのであれば、処理を簡単にするためにリストをフラット化します。

**`Python`**

```python title="Python"
# The response list comes back as a list of lists.
# Flatten out responses to a single list so you can build your .csv file.

flat_response_list = list(itertools.chain.from_iterable(responses))
```

### 4\.リストを選択し、.csv を作成する
リストがフラットの場合は、リスト内包表記を使用して、有用と思われるコメントそれぞれから要素を取得し、.csv ファイルに出力できます。少なくとも以下を含めることを推奨します。
* コメント - `text`
* 親 ID - `parent_id`
* アセット ID - `asset_id`
* アセット名 - `name`
* 所有者 ID - `owner_id`
* 所有者のメールアドレス - `owner.email`
* タイムスタンプ - `timestamp`
* 更新日時 - `updated_at`

アセットごとに必要な出力を含む新しいリストを最終出力用に作成したら、.csv ファイルに書き出します。

**`Python`**

```python title="Python"
list_for_csv = [[o['text'], o['parent_id'], o['asset_id'], o['name'], o['owner_id'], o['owner']['email'], o['timestamp'], o['updated_at']] for o in flat_response_list]

# Let's write our new list out to a .csv file. We'll add a heading.
with open("output.csv", 'w') as myfile:
     wr = csv.writer(myfile, dialect='excel')
     wr.writerow(['Comment', 'Parent ID', 'Asset ID', 'Asset Name', 'Owner ID', 'Email', 'Timestamp', 'Updated At'])
     wr.writerows(list_for_csv)
```

これで完了です。これで、Frame.io プロジェクト全体からのフラット化されたコメントを含む .csv ファイルが作成されました。