Apple script to move the mouse pointer on a specified word and click on it in Safari

Dear all,


I come to this site after an exhaustive and thorough googling and searching for a solution to my problem. What I want to achieve is to completely reveal absolutely all the comments under a YouTube video. Since there is no simple way to do this, currently I have to do this manually following these steps:


  1. scrolling to the bottom and clicking the "Show more" button until it disappearsUser uploaded file
  2. After doing that, I still don't get to see all the comments, next I have to CMD+F "view all " in order to find and reveal the comments hidden under all the "View all # replies" (e.g. "View all 5 replies" etc.)User uploaded file
  3. the final step is to CMD+F "Read more" in order to display the content of some longer comments that are normally hiddenUser uploaded file

So, basically, what I need an Apple Script that would do it for me.

  • First it would find the last string "Show more" and would click on it
  • Then it would try to find and click on it again until it's there no more
  • Then it would find all the "view all " and click on them
  • and finally it would find and click on all the "Read more"


Please, I would really appreciate if anyone could help me with this, you would save me so much time.
Thank you very much in advance.


PS: if you think I'm asking too much, could you just please tell me how to find a string and just click on it? Nothing else.

MacBook Pro, OS X El Capitan (10.11.1), Apple Script

Posted on Nov 14, 2015 8:59 AM

Reply
10 replies

Nov 16, 2015 1:09 AM in response to sinepgnol

Hello,



This script works on Safari.


tell application "Safari" -- the current page must be loaded
    repeat
        if (do JavaScript "document.getElementById('yt-comments-paginator').offsetParent === null" in document 1) is in {true, missing value} then exit repeat -- this element is hidden or not exists, so no more comments.
        do JavaScript "document.getElementById('yt-comments-paginator').getElementsByClassName('show-more')[0].click();" in document 1 -- click on the "Show more" button.
        my myDelay()
    end repeat
    do JavaScript "var myArray = document.getElementsByClassName('load-comments can-reply'); for (var x in myArray) { myArray[x].getElementsByTagName('a')[0].click();}" in document 1 -- click on every "view all .. replies" link
    do JavaScript "var myArray = document.getElementsByClassName('comment-text-toggle hid'); for (var x in myArray) { myArray[x].getElementsByTagName('a')[0].click();}" in document 1 -- click on every "Read more" link
end tell

on myDelay()
    do shell script "sleep 1"
end myDelay


But the name of some element may be different, if you have an extension that modify the content of the web page.

Nov 16, 2015 1:21 AM in response to Jacques Rioux

oh, I see, it's working. GREAT!!! Thank you very much!!! And while we are at this, may I have a last question for you? Could you please tell me how to modify this script in order to make it work for 9gag.com comments as well? There are just two buttons:

the "show more" button is called "Load More Comments" User uploaded file

and

the "View all # replies" button is called "Load More Replies"

User uploaded file

as for the "Read more" button known from YouTube

(User uploaded file), there is no such thing on 9gag.com.


Thank you very much in advance for your help!

Nov 16, 2015 11:11 AM in response to sinepgnol

Hi,


sinepgnol wrote:


Could you please tell me how to modify this script in order to make it work for 9gag.com comments as well?


Thank you very much in advance for your help!


Here is the script for 9gag.com:


tell application "Safari" -- for  9gag.com, the current page must be loaded
    repeat
        if (do JavaScript "document.getElementsByClassName('cmnt-btn more grey badge-load-more-trigger').length" in document 1) = 0 then exit repeat --  no more comments.  
        do JavaScript "document.getElementsByClassName('cmnt-btn more grey badge-load-more-trigger')[0].click();" in document 1 -- click on the "Load More comments" button.
        my myDelay("0.3") (*   0.3 second (it's OK on my computer)
        if there are still a "Load More comments" button when the script ends,  increase the delay (this is depending on the speed of your internet connection and according to the load on the processors. *)
    end repeat
    
    repeat -- need a loop, because nested  "Load More Replies..." link 
        if (do JavaScript "document.getElementsByClassName('collapsed-comment').length" in document 1) = 0 then exit repeat
        do JavaScript "myArray = document.getElementsByClassName('collapsed-comment');for (var x in myArray) {myArray[x].click()}" in document 1 -- click on every "Load More Replies..." link 
    end repeat
end tell

on myDelay(x)
    do shell script "sleep " & x
end myDelay

Dec 26, 2015 2:37 PM in response to sinepgnol

Hello,


sinepgnol wrote:


Dear Jacques Rioux,


I would like to ask you for one more little favor. Please, could you make a script for revelaing all the comments on reddit? There is just one button called "Load More Comments" so I just need the script to click on every occurence of "Load More Comments" until there are no more. Thank you very much in advance and merry christmas



When this button is clicked, it call a javascript function, so javascript is single threaded.

If the script use a javascript loop to click on every button, only the javascript's function on the first button is executed.


If the script use an AppleScript loop to click on every button:

The do javascript command prevents the execution of the javascript's function of the button.

Adding a short delay before each do javascript command: same issue.

Adding a medium delay before each do javascript command: sometime it's work, sometimes it will remain several buttons or all buttons.

Adding a long delay before each do javascript command: it's work, but it's long.



The best solution is to use an event listener:

The AppleScript add an event listener to the HTML page, and it click on the first "morecomments" button, this AppleScript will end in less than a fraction of a second.


After that, this is the HTML document that will do the rest:

When a button is removed from the HTML document, a notification is sent to the event listener, and the listener call a javascript function to click on another "morecomments" button.

So on until there is no "morecomments" button.


tell application "Safari" -- for reddit, the current page must be loaded
    do JavaScript "document.addEventListener('DOMNodeRemovedFromDocument', loadCMTS, true);function loadCMTS(){document.getElementsByClassName('morecomments')[0].firstChild.onclick();}; loadCMTS()" in document 1
end tell



Happy Holidays.

Apr 15, 2016 3:24 AM in response to Jacques Rioux

Hey Jacques Rioux,


currently I have the problem that I would like to run the script in Google Chrome because it caches more comments than Safari. I need about 45k comments for an academic research purpose, thats the issue.


I modified your script to the current youtube html-tags and changed it to Google Chrome:

tell application "Google Chrome" -- the current page must be loaded

repeat

if (do JavaScript "document.getElementById('comment-section-renderer').offsetParent === null" in document 1) is in {true, missing value} then exit repeat -- this element is hidden or not exists, so no more comments.

do JavaScript "document.getElementById('comment-section-renderer').getElementsByClassName('yt -uix-button yt-uix-button-size-default yt-uix-button-default load-more-button yt-uix-load-more comment-section-renderer-paginator yt-uix-sessionlink')[0].click();" in document 1 -- click on the "Show more" button.

do JavaScript "window.scrollTo(0,document.body.scrollHeight);" in document 1 -- scroll down

my myDelay()

end repeat

do JavaScript "var myArray = document.getElementsByClassName('load-comments can-reply'); for (var x in myArray) { myArray[x].getElementsByTagName('a')[0].click();}" in document 1 -- click on every "view all .. replies" link

do JavaScript "var myArray = document.getElementsByClassName('comment-text-toggle hid'); for (var x in myArray) { myArray[x].getElementsByTagName('a')[0].click();}" in document 1 -- click on every "Read more" link

end tell


on myDelay()


do shell script "sleep 1"

end myDelay



When I run the script in the editor it appears the error "syntax error: "," expected, but identifier found"


Do you have any idea where the problem might be?


Thanks in advance!

Best wishes.

Apr 15, 2016 8:36 AM in response to mart.buechner

Hi,


mart.buechner wrote:


I modified your script to the current youtube html-tags and changed it to Google Chrome:



When I run the script in the editor it appears the error "syntax error: "," expected, but identifier found"


Do you have any idea where the problem might be?




The command for Google Chrome is not the same, the syntax to run a javascript is:

execute (some Tab of the some window) javascript "some script"


Example:

For Safari : do JavaScript "var myArray = document.getElementsByClassName('load-comments can-reply'); for (var x in myArray) { myArray[x].getElementsByTagName('a')[0].click();}" in document 1 -- click on every "view all .. replies" link


ForGoogle Chrome :execute (active tab of window 1) javascript "var myArray = document.getElementsByClassName('load-comments can-reply'); for (var x in myArray) { myArray[x].getElementsByTagName('a')[0].click();}" -- click on every "view all .. replies" link

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Apple script to move the mouse pointer on a specified word and click on it in Safari

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.