JSON Parsing von youtube video comment replies

majume

Neues Mitglied
Hallo,

ich möchte kommentierte Kommentare von Youtube Videos abfragen und auslesen.

ich lese alle Kommentare (Top-Level & Replies) über diese Anfrage ein:
YTVideoID&key=YTtoken

Eine Beispielhafte Antwort kann dann so aussehen:

JSON:
{
    "kind": "youtube#commentThreadListResponse",
    "etag": "6ShaadijGwdvLrBaR48-7ApiGj0",
    "pageInfo": {
        "totalResults": 2,
        "resultsPerPage": 20
    },
    "items": [
        {
            "kind": "youtube#commentThread",
            "etag": "H0ZYp5OkKZaJ9Xp-niFYNUrvK0U",
            "id": "UgxSZPfTWpGofO30FOp4AaABAg",
            "snippet": {
                "videoId": "dpfrbHBTzjg",
                "topLevelComment": {
                    "kind": "youtube#comment",
                    "etag": "vcj6Nei_iPzSSiXItzqhFldx-pM",
                    "id": "UgxSZPfTWpGofO30FOp4AaABAg",
                    "snippet": {
                        "videoId": "dpfrbHBTzjg",
                        "textDisplay": "Mike tyson and snoop and if you listening to snoop songs and watch a Mike tyson fight it does not get better than that",
                        "textOriginal": "Mike tyson and snoop and if you listening to snoop songs and watch a Mike tyson fight it does not get better than that",
                        "authorDisplayName": "GEMMA MUDD",
                        "authorProfileImageUrl": "https://yt3.ggpht.com/ytc/AOPolaQvp7b-xAE5bd9vk5l-vk97Wk9404rC98BBAUtXug=s48-c-k-c0x00ffffff-no-rj",
                        "authorChannelUrl": "http://www.youtube.com/channel/UCPxdezfZx20GfUCQHNHYN5A",
                        "authorChannelId": {
                            "value": "UCPxdezfZx20GfUCQHNHYN5A"
                        },
                        "canRate": true,
                        "viewerRating": "none",
                        "likeCount": 0,
                        "publishedAt": "2023-07-09T08:04:04Z",
                        "updatedAt": "2023-07-09T08:04:04Z"
                    }
                },
                "canReply": true,
                "totalReplyCount": 0,
                "isPublic": true
            }
        },
        {
            "kind": "youtube#commentThread",
            "etag": "QZgYRmV3Dv3RYJz94nuc6nLWH_I",
            "id": "Ugx4SyzUrjyVO2U8aI94AaABAg",
            "snippet": {
                "videoId": "dpfrbHBTzjg",
                "topLevelComment": {
                    "kind": "youtube#comment",
                    "etag": "NMm8g3Ff9g13QDWoW0yeWEhlHAE",
                    "id": "Ugx4SyzUrjyVO2U8aI94AaABAg",
                    "snippet": {
                        "videoId": "dpfrbHBTzjg",
                        "textDisplay": "Yesssuh snooop😂😂😂",
                        "textOriginal": "Yesssuh snooop😂😂😂",
                        "authorDisplayName": "Chris Green",
                        "authorProfileImageUrl": "https://yt3.ggpht.com/b7MWsPSSH9cbzw_d1rkcH_pmmMZVKV_c0XF8vX2b25vnUUPww4sZI5yG-gv5lBDZ-cepNT5Y=s48-c-k-c0x00ffffff-no-rj",
                        "authorChannelUrl": "http://www.youtube.com/channel/UCWi8YIluYcVQnNDTqAADlwA",
                        "authorChannelId": {
                            "value": "UCWi8YIluYcVQnNDTqAADlwA"
                        },
                        "canRate": true,
                        "viewerRating": "none",
                        "likeCount": 1,
                        "publishedAt": "2023-07-09T03:57:48Z",
                        "updatedAt": "2023-07-09T03:57:48Z"
                    }
                },
                "canReply": true,
                "totalReplyCount": 1,
                "isPublic": true
            },
            "replies": {
                "comments": [
                    {
                        "kind": "youtube#comment",
                        "etag": "yZZy7JCdgcGoc-BUnrIsv59jG7E",
                        "id": "Ugx4SyzUrjyVO2U8aI94AaABAg.9rw5eYfNwCt9rw6y7a9-wr",
                        "snippet": {
                            "videoId": "dpfrbHBTzjg",
                            "textDisplay": "❤❤ Snooop ❤❤",
                            "textOriginal": "❤❤ Snooop ❤❤",
                            "parentId": "Ugx4SyzUrjyVO2U8aI94AaABAg",
                            "authorDisplayName": "New Podcast Bites ",
                            "authorProfileImageUrl": "https://yt3.ggpht.com/B9RKzQKAxGKgD9mjKJRmd81Bg0MATfkX3jTsvnG7zT8Ba8pconlO-1WpCjoItJ7CUrLId-BK=s48-c-k-c0x00ffffff-no-rj",
                            "authorChannelUrl": "http://www.youtube.com/channel/UCGNnYnWQ5LoBnmttz0HlS0Q",
                            "authorChannelId": {
                                "value": "UCGNnYnWQ5LoBnmttz0HlS0Q"
                            },
                            "canRate": true,
                            "viewerRating": "none",
                            "likeCount": 1,
                            "publishedAt": "2023-07-09T04:09:12Z",
                            "updatedAt": "2023-07-09T04:09:12Z"
                        }
                    }
                ]
            }
        }
    ]
}


ich weiß dann prinzipiell wie ich die Top-Level Kommentare auslesen kann:

Java:
 public static String parsecomments(String responseBody){

        JSONObject res = new JSONObject(responseBody.toString());
        for(int i=0;i<res.getJSONArray("items").length();i++) {
            String comments = res.getJSONArray("items").getJSONObject(i).getJSONObject("snippet").getJSONObject("topLevelComment").getJSONObject("snippet").getString("textDisplay");
            System.out.println(i+"-"+comments);
        }
        return null;
    }

Mein Ziel ist es nun den String "textDisplay" von "replies" auslesen

mein Lösungsansatz:

Java:
public static String parsesubcomments(String responseBody){

        JSONObject res = new JSONObject(responseBody.toString());
        for(int i=0;i<res.getJSONArray("comments").length();i++) {
         String comments = res.getJSONArray("items").getJSONObject(i).getJSONObject("replies").getJSONArray("comments").getJSONObject(i).getJSONObject("snippet").getString("textDisplay");
            System.out.println(i+"-"+comments);
        }
        return null;
    }

ich bekomme dann ein paar Fehlermeldungen:

Code:
Exception in thread "main" org.json.JSONException: JSONObject["comments"] not found.
    at org.json.JSONObject.get(JSONObject.java:570)
    at org.json.JSONObject.getJSONArray(JSONObject.java:763)
    at org.example.main.parsesubcomments(main.java:140)
    at org.example.main.main(main.java:72)

Ich kenne mich nicht so gut mit JSONs aus und schaffe es anscheinend nicht die Abfrage mit Arrays, Objects und Strings richtig zusammenzusetzen.
Zum anderen habe ich 2 Arrays, muss ich dann 2 Schleifen verwenden?
 
Wenn Du das JSON von Hand durchgehen willst, dann musst Du es auch wirklich Ebene für Ebene durchgehen. Also erst die items, da dann für jedes Element des Arrays weiter in die Tiefe gehen, bis Du die comments erreicht hast.

Aber bei so JSON ist es einfacher, die Struktur der JSON Antwort nachzubilden um dann mit einer Library wie Jackson oder GSON aus dem JSON eine Objektinstanz zu bekommen. Und diesbezüglich wird es bestimmt fertige Implementierungen geben. Ich würde mich wundern, wenn es für Youtube APIs keine Java Libraries geben würde.
 
Danke für deine Antwort. Das gab mir einen neuen Denkanstoß.
Ich löse es jetzt einfach anders. Ich hole mir zunächst alle TopLevel Comment IDs.

und dann lasse ich mir für jede TopLevel ID, die IDs der Replies auflisten:
commentID&key=token

und dann lass ich mir von jedem Kommentar den Text anzeigen:
commentID&key=token&part=snippet

und schließlich kann ich dann recht einfach den Text holen:
Java:
    public static String parseallcomments(String responseBody){

        JSONObject res = new JSONObject(responseBody.toString());
        for(int i=0;i<res.getJSONArray("items").length();i++) {
            String comments = res.getJSONArray("items").getJSONObject(i).getJSONObject("snippet").getString("textDisplay");
            System.out.println(comments);
        }
        return null;
    }
 
Wobei das nicht das ist, was ich vor Augen hatte. Du gehst immer noch manuell das JSON durch.

Die Idee ist, dass Du die Struktur vom JSON in eigenen Klassen abbildest. Und dann arbeitest Du nicht mehr mit dem JSON selbst sondern nutzt eine Library wie gson, um aus dem JSON eine Datenstruktur zu erzeugen. Dann wird das alles deutlich einfacher, da Du dann z.B. nur noch eine List durchgehen musst und so.
 

Zurück
Oben