...

Coletando comentários do Youtube usando o Youtube Data API - Parte 2

kim kataguiri

Criando uma função para coletar os comentários

A API do Google, assim como outras APIs, tem um limite de solicitação diária, para acessar e ver seu limite e acompanhar seu uso entre no console do desenvolvedor do Google e no final da página clique em Youtube Data API v3, você será direcionado para a página da API.

Um vídeo pode ter de 10 a mais de 30 mil comentários, então vale a pena dar uma olhada no seu uso diário após usar a API.

Agora, vamos implementar a função em um arquivo separado, então vamos começar importando a biblioteca da API.

import googleapiclient.discovery

Depois, vamos implementar a função.

def collect_comments(video_id, page_token): """ This function list comments of a youtube video :param video_id: id of the youtube video, after ?v= -> youtube.com/watch?v=video_id :param page_token: :return: return 100 comments """ my_api_key = 'your key' api_service_name = "youtube" api_version = "v3" youtube = googleapiclient.discovery.build( api_service_name, api_version, developerKey=my_api_key) results = youtube.commentThreads().list( part="snippet,replies", maxResults=100, videoId=video_id, textFormat="plainText", pageToken=page_token ).execute() print('100 comments returned') return results

Os parâmetros part e maxResults são iguais à função que usamos para coletar dados de vídeo, apenas as propriedades mudam um pouco, você pode ver essas propriedades na documentação. Para o nosso caso, vamos usar o snippet e as respostas que contêm o conteúdo da mensagem e as demais informações como curtidas, data de publicação, etc.

Eu escolhi coletar as respostas dos comentários, para aumentar nossas amostras e assim termos mais conteúdo e palavras-chave para analisar, isso é uma coisa boa, a modelagem de tópicos funciona melhor com amostras maiores. A API tem uma limitação técnica de não coletar as respostas das respostas, então algumas vezes você vai notar que o número de comentários coletados é menor do que o número de comentários do vídeo.

Outro parâmetro é o video_id, usamos o id do vídeo para especificar em qual vídeo iremos coletar os comentários, este id é encontrado depois de ?v= no site do vídeo. Por exemplo, o ID do vídeo de https://www.youtube.com/watch?v=bM7SZ5SBzyY&ab_channel=NoCopyrightSounds é bM7SZ5SBzyY.

Como vimos antes, os maxResults limitam o número de dados retornados pela função, sendo 100 seu valor máximo, comentei que é possível coletar mais do que o valor máximo nos permite, para isso, precisamos do nextPageToken que é um token retornado pela função, este token aponta para a próxima página, nós o usamos para continuar de onde paramos.

Armazenando os comentários em um arquivo

Para armazenar os comentários em um arquivo, usaremos a mesma lógica que usamos na parte 1, vamos selecionar os campos que queremos e escrevê-los em um arquivo JSON. Para isso, vamos conhecer a estrutura dos dados retornados, observe a seguir.

{'kind': 'youtube#commentThreadListResponse', 'etag': '------', 'nextPageToken': '--------', 'pageInfo': {'totalResults': 100, 'resultsPerPage': 100}, 'items': [{ 'kind': 'youtube#commentThread', 'etag': '-', 'id': '-------', 'snippet': { 'videoId': 'MX82C2rQSXo', 'topLevelComment': {'kind': 'youtube#comment', 'etag': '---', 'id': '---', 'snippet': { 'videoId': 'MX82C2rQSXo', 'textDisplay': "", 'textOriginal': "", 'authorDisplayName': '', 'authorProfileImageUrl': 'image', 'authorChannelUrl': '', 'authorChannelId': { 'value': 'UCOJQ9Bw2J-kYoJLp4J5apZA'}, 'canRate': True, 'viewerRating': 'none', 'likeCount': 0, 'publishedAt': '2020-02-06T13:29:59Z', 'updatedAt': '2020-02-06T13:29:59Z'}}, 'canReply': True, 'totalReplyCount': 0, 'isPublic': True}},

As informações que o usuário pode editar como nome do canal e mensagem de texto são divididas em Original e Display, sendo Original as informações no momento da criação e Display as informações após a última atualização realizada pelo usuário até o momento da solicitação.

Uma observação importante, como o usuário pode editar as informações a qualquer momento, as informações que coletamos hoje podem ser diferentes amanhã, apenas as informações originais permanecem inalteradas. O campo updatedAt mostra quando foi realizada a última modificação, e o campo publishedAt quando foi publicado.

A partir das informações retornadas, selecionaremos o nome atual do autor (authorDisplayName), o texto atual dos comentários (textDisplay), a data da última atualização (updateAt) e o número de curtidas (likeCount). Observe a função abaixo.

def write_json_file(comments, name): """ This function saves comments in a txt file :param comments: collected comments :param name: name for the txt file :return: a txt file """ text = '' for item in comments: comment = item["snippet"]["topLevelComment"]["snippet"] text += 'author: ' + comment['authorDisplayName'] + '\n' text += 'comment: ' + comment["textDisplay"].replace("\n", ". ") + '\n' text += 'date: ' + comment["updatedAt"] + '\n' text += 'like: ' + str(comment["likeCount"]) + '\n\n' if 'replies' in item.keys(): replies = item["replies"]["comments"] text += '\nreplies: \n' for reply in replies: text += 'author: ' + reply["snippet"]['authorDisplayName'] + '\n' text += 'comment: ' + reply["snippet"]["textDisplay"].replace("\n", ". ") + '\n' text += 'date: ' + reply["snippet"]["updatedAt"] + '\n' text += 'like: ' + str(reply["snippet"]["likeCount"]) + '\n\n' with open('database/comments/' + name + '.txt', '+a', encoding="utf8") as file: file.write(text) print('Information was stored in txt file')

Chamando as funções

videos = ['MX82C2rQSXo'] for video in videos: try: comment_data = collect_comments(video, '') while True: write_json_file(comment_data['items'], video) comment_data = collect_comments(video, comment_data['nextPageToken']) except KeyError: print('Comments successfully collected')

A variável page_token possui o token da página atual, no início está vazio apontando para a primeira página, então a função retorna a primeira página de comentários, depois disso, usamos o nextPageToken para a função coletar os comentários da próxima página, por último colocamos este código que está usando o nexPageToken em um loop, dessa forma ele coleta os comentários de todas as páginas. Na última página, ele retorna um token inválido e levanta um erro KeyError, quando isso ocorre significa que não há próxima página, então o algoritmo finaliza o loop.

O código está disponível no meu github e algumas vezes eu o atualizo. Sinta-se à vontade para editar o código adaptando-o às suas necessidades.

1

Ir para a página

2

Minhas mídias sociais 😊

Meu portfolio

lattes curriculum

Contate-me 🤗

mail

tsukasa.renato@gmail.com

14 997468186