2012-10-10 15 views
5

Cerca di catturare tutti i commenti da un determinato video, piuttosto che andare una pagina alla volta.Come ottenere tutti i commenti di YouTube con il modulo gdata di Python?

from gdata import youtube as yt 
from gdata.youtube import service as yts 

client = yts.YouTubeService() 
client.ClientLogin(username, pwd) #the pwd might need to be application specific fyi 

comments = client.GetYouTubeVideoComments(video_id='the_id') 
a_comment = comments.entry[0] 

Il codice precedente con consentono di afferrare un singolo commento, probabilmente il commento più recente, ma sto cercando un modo per afferrare tutti i commenti in una sola volta. Questo è possibile con il modulo di Python?


La documentazione API di YouTube per comments, feed dei commenti docs e Python API docs

+0

Questo è stato risposto [qui] (http://stackoverflow.com/questions/10941803/using-youtube-api-to-get-all-comments-from-a-video-with-the-son-feed) con una soluzione che utilizza PHP, poiché l'API PHP di YouTube ha una chiamata che lo consente. Non penso che una pura risposta di Python sia là fuori. –

+0

@ KenB Ho visto anche questo. È un peccato. Il video in questione ha 9k commenti e non credo che fare le chiamate a 360 'GetNextLink' sia il modo migliore. – TankorSmash

+1

L'URL 'www.youtube.com/all_comments? V = video_id' ha un elenco di commenti analizzabili, ma è un lungo caricamento. Supponiamo che potrei provarlo. – TankorSmash

risposta

7

Di seguito realizza quello che hai chiesto per l'utilizzo del Python YouTube API:

from gdata.youtube import service 

USERNAME = '[email protected]' 
PASSWORD = 'a_very_long_password' 
VIDEO_ID = 'wf_IIbT8HGk' 

def comments_generator(client, video_id): 
    comment_feed = client.GetYouTubeVideoCommentFeed(video_id=video_id) 
    while comment_feed is not None: 
     for comment in comment_feed.entry: 
      yield comment 
     next_link = comment_feed.GetNextLink() 
     if next_link is None: 
      comment_feed = None 
     else: 
      comment_feed = client.GetYouTubeVideoCommentFeed(next_link.href) 

client = service.YouTubeService() 
client.ClientLogin(USERNAME, PASSWORD) 

for comment in comments_generator(client, VIDEO_ID): 
    author_name = comment.author[0].name.text 
    text = comment.content.text 
    print("{}: {}".format(author_name, text)) 

Purtroppo l'API limita il numero di voci che possono essere recuperati a . Questo è stato l'errore ho avuto quando ho provato una versione ottimizzato con una mano artigianale GetYouTubeVideoCommentFeed parametro URL:

gdata.service.RequestError: {'status': 400, 'body': 'You cannot request beyond item 1000.', 'reason': 'Bad Request'} 

Si noti che lo stesso principio dovrebbe valere per recuperare le voci in altri alimenti della API.

Se si vuole Hand craft il parametro GetYouTubeVideoCommentFeed URL, il suo formato è il seguente: si applicano

'https://gdata.youtube.com/feeds/api/videos/{video_id}/comments?start-index={sta‌​rt_index}&max-results={max_results}' 

le seguenti limitazioni: start-index <= 1000 e max-results <= 50.

+1

Grande. Sai se esiste un modo per impostare manualmente 'start_index' o' items_per_page'? Impostarlo sul primo set di commenti non sembra fare nulla. – TankorSmash

+1

Hai solo bisogno di passare un URL con il seguente formato a 'GetYouTubeVideoCommentFeed':' https://gdata.youtube.com/feeds/api/videos/{video_id}/comments?start-index={start_index}&max-results = {} MAX_RESULTS '. Si applicano le seguenti restrizioni: 'start-index <= 1000' e' max-results <= 50'. –

+0

Fantastico, non ho nemmeno pensato di alterare l'URI, evviva! – TankorSmash

1

L'unica soluzione che ho per ora, ma non è utilizzando l'API e diventa lento quando c'è diverse migliaia Commenti.

import bs4, re, urllib2 
#grab the page source for vide 
data = urllib2.urlopen(r'http://www.youtube.com/all_comments?v=video_id') #example XhFtHW4YB7M 
#pull out comments 
soup = bs4.BeautifulSoup(data) 
cmnts = soup.findAll(attrs={'class': 'comment yt-tile-default'}) 
#do something with them, ie count them 
print len(cmnts) 

Nota che a causa di 'classe' essere un nome di pitone incorporato, non si può fare ricerche normali per 'startwith' tramite espressioni regolari o lambda come visto here, dal momento che si sta utilizzando un dict, sui parametri regolari . Diventa anche piuttosto lento a causa di BeautifulSoup, ma deve essere utilizzato perché etree e minidom non trovano i tag corrispondenti per qualche motivo. Anche dopo prettyfying() con bs4

+0

Ciao, risposta di interesse ma penso che la struttura html sia cambiata. Usi un tag alternativo invece di 'comment yt-tile-default'? Grazie! – Thoth

+0

@Questo non ne ho fatto uso da un po 'di tempo, ma apro gli strumenti di sviluppo e modifica la mia risposta se trovi – TankorSmash

Problemi correlati