2012-10-10 2 views
5

Sie möchten alle Kommentare zu einem bestimmten Video abrufen, statt nur eine Seite nach der anderen zu lesen.Wie erhalte ich alle YouTube-Kommentare mit Pythons gdata-Modul?

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] 

Der obige Code mit können Sie einen einzigen Kommentar greifen, wahrscheinlich den letzten Kommentar, aber ich bin auf der Suche nach einem Weg, alle die Kommentare auf einmal zu greifen. Ist das mit Pythons gdata Modul möglich?


Die Youtube API-Dokumentation für comments, den Kommentar-Feed docs und der Python API docs

+0

Dies wurde [hier] beantwortet (http://stackoverflow.com/questions/10941803/using-youtube-api-to-get-all-comments-from-a-video-with-the-json-feed) mit einer Lösung, die PHP nutzt, da die YouTube PHP API einen Aufruf hat, der es erlaubt. Ich glaube nicht, dass es eine pure Python-Antwort gibt. –

+0

@KenB Das habe ich auch gesehen. Das ist eine Schande. Das fragliche Video hat 9k Kommentare und ich denke nicht, 360 'GetNextLink'-Aufrufe zu machen ist der beste Weg. – TankorSmash

+1

Die URL 'www.youtube.com/all_comments? V = video_id' hat eine Parse-Kommentar-Liste, aber es ist eine lange Ladezeit. Angenommen, ich könnte das versuchen. – TankorSmash

Antwort

7

Nachfolgend erreicht, was Sie für die Verwendung der Python YouTube API gestellt:

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)) 

Leider ist die API, um die Anzahl der Einträge begrenzt, die auf abgerufen werden können. Das war der Fehler, den ich bekam, als ich eine gezwickt Version mit einer Hand versuchte GetYouTubeVideoCommentFeed URL-Parameter gefertigt:

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

Beachten Sie, dass das gleiche Prinzip anwenden sollte Einträge in anderen Feeds der API abgerufen werden.

Wenn Sie die GetYouTubeVideoCommentFeed URL-Parameter übergeben wollen Handwerk, ist das Format:

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

gelten die folgenden Einschränkungen: start-index <= 1000 und max-results <= 50.

+1

Großartig. Weißt du, ob es eine Möglichkeit gibt, den 'start_index' oder' items_per_page' manuell zu setzen? Es auf die erste Reihe von Kommentaren zu setzen scheint nichts zu tun. – TankorSmash

+1

Sie müssen nur eine URL mit folgendem Format an "GetYouTubeVideoCommentFeed" übergeben: "https://gdata.youtube.com/feeds/api/videos/{video_id}/comments?start-index={start_index}&max-results = {max_results} '. Es gelten folgende Einschränkungen: 'start-index <= 1000' und' max-results <= 50'. –

+0

Großartig, dachte nicht einmal daran, die URI zu ändern, Prost! – TankorSmash

1

Die einzige Lösung, die ich jetzt habe, aber es ist nicht mit der API und langsam werden, wenn es mehrere gibt tausend Bemerkungen.

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) 

Beachten Sie, dass aufgrund der ‚Klasse‘ Name eine eingebaute Python zu sein, können Sie regelmäßige Suche nach ‚startwith‘ über regex oder Lambda-Ausdrücke nicht als here gesehen, da Sie eine dict verwenden, über regelmäßige Parameter . Es wird auch ziemlich langsam wegen BeautifulSoup, aber es muss verwendet werden, weil etree und nicht passende Tags aus irgendeinem Grund finden. Auch nach prettyfying() mit bs4

+0

Hallo, Interesse Antwort, aber ich denke, dass die HTML-Struktur geändert hat. Verwenden Sie ein alternatives Tag anstelle von 'comment yt-tile-default'? Vielen Dank! – Thoth

+0

@Thoth Ich habe das schon lange nicht mehr genutzt, aber öffne die Dev-Tools und bearbeite meine Antwort, wenn du es herausfindest, – TankorSmash

Verwandte Themen