LooseStool

ytComments -- grab #youtube Comments & expand replies

Dec 8th, 2019
647
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ytComments -- grab #youtube Comments & expand replies
  2.  
  3. by @LooseStool https://Gab.com/LooseStool -- 08Dec2019 ... #Bookmarklet available on #PasteBin https://pastebin.com/iWJcKmGt
  4.  
  5. Linked from https://gab.com/LooseStool/posts/103275509846816166 , quoting https://gab.com/LooseStool/posts/103114945716431086 ( which was a reply to https://gab.com/LooseStool/posts/103114786392290752 )
  6.  
  7. A hopefully-helpful BOOKMARKLET; right now it only** works in Firefox and Brave/Chrome (preferred, better output)...
  8.  
  9. Each click triggers loading of the next full page comments and also auto-clicks to expand all replies and "Read More" (the lengthier comments)
  10.  
  11. Results appear in F12 console of web browser -- you can copy to the clipboard the FULL CONVERSATION while videos are still up ( to me that's a huge part of the value of youtube ... or at least it WAS :-( )
  12.  
  13. For usage yt$${options} see: yt$$.help
  14.  
  15. ** NOTE: MS Internet Explorer not working right now -- does not have scrollIntoView(false), PLUS uses DIFFERENT html elements ids and classes
  16. ...and MS EDGE has a limit of 2029 characters for Favorites/Bookmarklets :-(
  17. ...and did not try any other browsers, including mobile. No promises or guarantees use at your own risk etc.
  18.  
  19. var setHelp = function() {
  20.     var msg = "\n>>> After 1st click of Bookmarklet, you can also relaunch from within web browser F12 console: yt$$( {options} );\n\n"
  21.         + "{ skipConsoleClear: true } means SKIP the console.clear() before each run\n"
  22.         + "{ skipVideoInfo: true } means SKIP calling getYoutubeVideoInfo() to insert those results into the start of getYoutubeComments()\n"
  23.         + "{ shouldPromptIfFirstTime: true } means getYoutubeVideoInfo will also prompt( 'for easier copypasta (ONLY ONE TIME PER VIDEO_ID)', results )\n"
  24.         + "\nTo call with all Bookmarklet DEFAULT values: yt$$(true)" + " yt$$( { skipConsoleClear: " + DEFAULT_OPTIONS.skipConsoleClear
  25.         + ", skipVideoInfo: " + DEFAULT_OPTIONS.skipVideoInfo + ", shouldPromptIfFirstTime: " + DEFAULT_OPTIONS.shouldPromptIfFirstTime + " } )\n"
  26.         + "To clear all 'yt$$.rundata' *and therefore bring back the prompt()*: yt$$.reset()\n"
  27.         + "To see this help usage message again: yt$$.help\n";
  28.     console.log( T.help = msg );
  29. };
  30.  
  31. UPDATED 09DEC2019: now includes video's FULL DESCRIPTION -- including any hyperlinks fully auto-expanded , no more "..." annoyance!
  32.  
  33. ...
  34.  
  35. javascript: window.yt$$=window.yt$$||function(e){var n=yt$$,t=String.fromCharCode(9),r=String.fromCharCode(1),o={skipConsoleClear:!1,skipVideoInfo:!1,shouldPromptIfFirstTime:!0};e=1==e?o:e||{};var a=!!e.skipConsoleClear,i=!!e.skipVideoInfo,l=!!e.shouldPromptIfFirstTime,c=(n.reset=function(){yt$$=void 0},function(){$();var t=I(i,l),o=t[0],c=(t[1],m(t));return!a&&console.clear&&console.clear(),console.log(o.replace(r,c)),console.log(c),console.log(e),console.log(n.rundata),n.help||b(),n.rundata}),u=function(e){if(e=e||location.href,!window.ytplayer||!ytplayer.config)throw new TypeError("getYoutubeVideoInfo ["+e+"] expected object [window.ytplayer.config] is unavailable");return e},s=function(){for(var e=function(e,n,t){e.click&&e.click()},n=arguments.length,t=0;n>t;t++)for(var r=y(arguments[t]),o=r.length,a=0;o>a;a++)e(r[a],a,r)},p=function(e,n){var t=y(e)[n||0];t&&t.scrollIntoView&&t.scrollIntoView(!1)},d=function(){var e=w(v("div#description>.content"));if(e.indexOf("...")>-1)for(var n=y("div#description>yt-formatted-string>a.yt-formatted-string"),t=n.length,r=0;t>r;r++){var o=n[r].href.replace(/^(.+?\bredirect.*?q=)([^&\r\n]*)(.*)$/,"$2");e=e.replace(n[r].text,decodeURIComponent(o))}return e},g=function(e){var n=e.replace(/\r\n/g,"\n").replace(/\r/g,"\n").replace(/\n/g,"\n").split(/\n[ \t]*\d+ (?:second|minute|hour|day|week|month|year)s? ago(?: \(edited\))?\n/g),t=n.length-1;return t},f=function(e){var n=e.replace(/\s*[?]+/g,"_").replace(/["]/g,"'").replace(/\s*[:|]+\s*/g," - ").replace(/[*<>\/\\]/g,"-");return n},m=function(e){var n=w(v("div.watch-view-count")||v("div#count",1)||v("div#count",0)),r=w(v("h2.comment-section-header-renderer")||v("h2#count")),o="Current Comments: ~ "+e[1]+t+"String.length="+e[0].length,a=n+(r?t+r+" Total":"")+t+o,i=/[^\w ,.~=:\t]+/g;return a.replace(i,"").replace(/(\s)+/g,"$1")},h=function(e,n,t){e.rundata=e.rundata||{},e.rundata[n]=e.rundata[n]||[];var r=e.rundata[n].length,o=!r;return e.rundata[n][r]=t,o},v=function(e,n){var t=y(e),r=t[n||0];return r?r.innerText:""},y=function(e){return document.querySelectorAll(e)},w=function(e){if(e.trim)return e.toString().trim();var n=";0009;000B;000C;0020;00A0;FEFF;000A;000D;2028;2029".replace(/;/g,"\\u");return e.toString().replace(new RegExp("^["+n+"]+|["+n+"]+$","g"),"")},$=n.loadYoutubeComments=function(e){return(e=u(e))?(s("#more-replies","#continuation"),s("#more"),s("div#continuation>yt-next-continuation>paper-button"),void p("#continuations",0)):!1},I=n.getYoutubeComments=function(e,n){var t=function(e){return e.replace(/\r\n/g,"\n").replace(/\r/g,"\n").replace(/\n/g,"\n").replace(/\n[ \t]*\d+ (?:second|minute|hour|day|week|month|year)s? ago(?: \(edited\))?\n/g,"\n").replace(/\n[ \t]*(?:Hide|View)(?: \d+|) repl(?:y|ies)(?: from .+)?\n/g,"\n").replace(/\n[ \t]*Show more replies\n/g,"\n").replace(/\n[ \t]*Show less|Read more\n/g,"\n").replace(/\n[ \t]*\d+\nREPLY\n/gi,"\n REPLY\n").replace(/[ \t]*\n/g,"\n").replace(/\n[ \t]*/g,"\n").replace(/\n{2,}/g,"\n\n ").replace(/\n ?REPLY\n/g,"\n\n").replace(/\n/g,"\r\n")},o=v("#contents.ytd-item-section-renderer")+"\n",a=d(),i=(a?a+"\n\n...\n\n":"")+t(o);if(e)return i;var l=C("",n),c=g(o);return[l+"\n\n"+r+"\n\n"+i,c]},C=n.getYoutubeVideoInfo=function(e,r){if(!(e=u(e)))return!1;var o=function(e,n){var t=("&"+((n||location.href)+"#").split("#")[0].split("?")[1]).split("&"+e+"=")[1];return void 0===t||null===t?null:decodeURIComponent((t+"&").split("&")[0])},a="https://www.youtube.com/watch?v={video_id}{TAB}{videoTitle} ({channelTitle} {dd}{Mon}{yyyy} {video_id})",i=o("v"),l=v("h1>span.watch-title")||v("h1.title"),c=v("div.yt-user-info")||v("#channel-name"),s=1e3,p=(new Date(ytplayer.config.args.timestamp*s),/[^\w ,-]/g),d=(v("div#watch-uploader-info")||v("#date")).replace(p,""),g=/^.+?(\b[^ -]+[ -]+[^ -]+[ -]+[^ -]+) *$/g,m=d.replace(g,"$1"),y=new Date(m),$=("0"+y.getDate()).substr(-2),I=y.getMonth(),C="JanFebMarAprMayJunJulAugSepOctNovDec".substring(3*I,3*I+3),b=1900+y.getYear(),T=a.replace(/{video_id}/g,i).replace(/{TAB}/g,t).replace(/{channelTitle}/g,w(c)).replace(/{dd}/g,$).replace(/{Mon}/g,C).replace(/{yyyy}/g,b),k=f(l),E=T.replace(/{videoTitle}/g,w(k));T=T.replace(/{videoTitle}/g,w(l));var V=h(n,i,new Date);return V&&r&&prompt("for easier copypasta (ONLY ONE TIME PER VIDEO_ID)",E),T==E?T:T+"\n"+E},b=function(){var e="\n>>> After 1st click of Bookmarklet, you can also relaunch from within web browser F12 console: yt$$( {options} );\n\n{ skipConsoleClear: true } means SKIP the console.clear() before each run\n{ skipVideoInfo: true } means SKIP calling getYoutubeVideoInfo() to insert those results into the start of getYoutubeComments()\n{ shouldPromptIfFirstTime: true } means getYoutubeVideoInfo will also prompt( 'for easier copypasta (ONLY ONE TIME PER VIDEO_ID)', results )\n\nTo call with all Bookmarklet DEFAULT values: yt$$(true) // yt$$( { skipConsoleClear: "+o.skipConsoleClear+", skipVideoInfo: "+o.skipVideoInfo+", shouldPromptIfFirstTime: "+o.shouldPromptIfFirstTime+" } )\nTo clear all 'yt$$.rundata' *and therefore bring back the prompt()*: yt$$.reset()\nTo see this help usage message again: yt$$.help\n";console.log(n.help=e)};return c()},void yt$$(true);
Advertisement
Add Comment
Please, Sign In to add comment