Applescript run Safari in background - applescript

I have an applescript that is now doing what I want it to do: Open a specific URL, close the page and wait 2 seconds then do it again. The script works.
The problem is that when I run this on my machine, and I am trying to do something else at the same time, the Safari windows keeps popping up. I would really like to run this in the background so that I can continue to work on whatever I am doing.
The code I have is:
set theURL to "https://sites.google.com/site/whatever/"
repeat 100 times
tell application "Safari"
activate
try
tell window 1 to set current tab to make new tab --with properties {URL:theURL}
set URL of document 1 to theURL
on error
open location theURL
end try
delay 2
try
close window 1
end try
end tell
tell application "Safari"
quit
end tell
delay 1
end repeat
Anyone have a solution to this one?

Safari is coming to the front because you are activating it within the loop.
repeat 100 times
tell application "Safari"
if not (exists document 1) then reopen
set URL of document 1 to "https://sites.google.com/site/whatever/"
delay 2
close window 1
quit
end tell
delay 1
end repeat
EDIT
set myURLs to {"https://www.google.com/", "http://www.yahoo.com/"}
repeat with aUrl in myURLs
repeat 100 times
tell application "Safari"
if not (exists document 1) then reopen
set URL of document 1 to aUrl
delay 2
close window 1
quit
end tell
delay 1
end repeat
end repeat

Related

Applescript, "A class name can't go after this identifier error", what does it mean?

Someone tried to help me set up a keyboard macro using a program called keyboard maestro on macos to control youtube, his example had safari:
set tabURL to "YouTube.com"
tell application "Safari"
set windowsList to index of every window
repeat with i in windowsList
try
tell window i
set current tab to (first tab whose URL contains tabURL)
end tell
set index of window i to 1
exit repeat
end try
end repeat
end tell
It worked, I simply changed the name safari to google chrome, I put in this code:
set tabURL to "YouTube.com"
tell application "Google Chrome"
set windowsList to index of every window
repeat with i in windowsList
try
tell window i
set current tab to (first tab whose URL contains tabURL)
end tell
set index of window i to 1
exit repeat
end try
end repeat
end tell
it gave me this error message
2020-09-10 15:02:26 Execute an AppleScript failed with script error: text-script:165:176: script error: A class name can’t go after this identifier. (-2740)
what does it mean? any help appreciated.
tell application "Google Chrome"
repeat with thisWindow in windows
set cnt to 1
repeat with thisTab in (tabs of thisWindow)
if URL of thisTab contains "youtube.com" then
set active tab index of thisWindow to cnt
set index of thisWindow to 1
exit repeat
end if
set cnt to cnt + 1
end repeat
end repeat
end tell
this is the fix if anyone cares.

AppleScript does not run from calendar

I made the following code to open a website, insert some required text, click "View", and download the resulting document. It runs perfectly if I manually click on it. It also works if I schedule a calendar event to call it when I am sitting in front of my Mac. I have tried every combination of keeping the display on/off and screen unlocked/locked. For some reason, it doesn't seem to work at 5:30am and 2:00pm when I set it to run. I have checked to make sure the disk and Mac are not going to sleep as well. Any thoughts on what I am doing wrong would be greatly appreciated.
--Quit Safari before the program starts
tell application "Safari"
close every window
end tell
--empty "Downloads" folder
tell application "System Events"
delete (every file of folder ("/Users/97pubs/Downloads"))
end tell
--opens DINS website
tell application "Safari"
make new document with properties {URL:"https://www.notams.faa.gov/dinsQueryWeb/"}
activate
ignoring white space
tell front document to repeat until its text contains "About DINS"
end repeat
end ignoring
log "Finished loading"
end tell
delay 2
--Function to press DoD banner on DINS website
to clickClassName(theClassName, elementnum)
tell application "Safari"
do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
end tell
end clickClassName
clickClassName("ui-state-default", 0)
delay 2
--Function to input ICAO abbreviations on the page
to inputByName(theName, num, theValue)
tell application "Safari"
do JavaScript "
document.getElementsByName('" & theName & "')[" & num & "].value ='" & theValue & "';" in document 1
end tell
end inputByName
inputByName("retrieveLocId", 0, "kmaf")
delay 2
--Function to click "View NOTAMs" on page
to clickName(theName, elementnum)
tell application "Safari"
do JavaScript "document.getElementsByName('" & theName & "')[" & elementnum & "].click();" in document 1
end tell
end clickName
--Clicks "View NOTAMs" on page
clickName("submit", 0)
--Waits for next window to completely load before continuing
tell current application
tell application "Safari"
tell window 1
repeat until (exists tab 2)
delay 1
end repeat
ignoring white space
tell front tab to repeat until its text contains "DINS Disclaimer"
end repeat
end ignoring
end tell
end tell
end tell
delay 1
--Clicks "Save all NOTAMs" on page
clickName("button", 1)
delay 2
--Waits for download to complete before continuing
set someFolder to "/Users/path/to/save/location/" -- put your download folder path here
if not (waitForFilesToCopy into someFolder for (10 * minutes)) then
display alert "Error with downloads" message "The downloads did not complete in the time allowed."
if button returned of the result is "Cancel" then error -128
end if
to waitForFilesToCopy into theFolder for timeToWait
(*
waits up to the timeToWait for files to be copied/downloaded to theFolder the test is based on the size of the folder not changing after several seconds the rough timeToWait may need to be adjusted if copying several files/folders parameters - theFolder [mixed]: the folder to check timeToWait [integer]: a maximum timeout value in seconds returns [boolean]: true if copy/download finished, false if timeout
*)
set {theFolder, possible, interval} to {theFolder as text, false, 2} -- change the check interval as desired
tell application "System Events" to set currentSize to size of disk item theFolder -- get initial size
repeat (timeToWait div interval) times -- check every interval seconds
delay interval
tell application "System Events" to set newSize to size of disk item theFolder -- recheck size
if (newSize is equal to currentSize) then
if possible then -- no change since last time
return true -- success
else -- one more time...
set possible to true
end if
else -- update size & possible switch
set {currentSize, possible} to {newSize, false}
end if
end repeat
return false -- fail (timeout)
end waitForFilesToCopy
--Rename PDF to "5 Local NOTAMs.pdf"
tell application "System Events" to set name of file "/Users/path/to/save/location/temp.pdf" to "5 Local NOTAMs.pdf"
--Move NOTAMs to "CrewPapers" folder
tell application "Finder"
move POSIX file "/Users/path/to/save/location/5 Local NOTAMs.pdf" to POSIX file "/Users/path/to/new/location" with replacing
end tell
--Close Safari and Preview windows
tell application "Safari"
close every window
end tell
tell application "Preview"
close every window
end tell

Apple script find and replace text

So, right now my code clicks on a textarea in safari then it adds a word using keystroke, however I was wondering if there is a way to find and replace a word in that area and also is there a way to replace a highlighted word without keystroke?
Current code:
Sorry its very very poorly formatted since I am pretty bad at applescript
to clickClassName(theClassName, elementnum)
tell application "Safari"
do JavaScript "document.getElementsByClassName('" & theClassName & "')[" & elementnum & "].click();" in document 1
end tell
end clickClassName
to clickID(theId)
tell application "Safari"
do JavaScript "document.getElementById('" & theId & "').click();" in document 1
end tell
end clickID -- All the code up to this point did is allow me to click on IDs and classes in safari.
tell application "Safari" to activate
tell application "System Events"
tell application "Safari"
tell window 1
set current tab to (make new tab with properties {URL:"https://en.wikipedia.org/w/index.php? title=User:USERNAMEHERE/sandbox&action=edit"})
end tell
end tell
end tell
delay 2 -- All the code up to this point from the last comment did is open a new tab in safari.
repeat 5 times
set randomlist to {"1","2","3","4"} -- List of numbers that will be randomly selected and put in the texarea
set randomword to some item of randomlist
clickClassName("tool-button wikiEditor-toolbar-spritedButton", 0) -- This clicks the bold button on the sandbox page
tell application "System Events"
tell process "Safari"
keystroke randomword -- Uses keystroke to put replace the text inside the bold formatting area
end tell
end tell
delay 1
clickID("wpSave") -- Clicks save
delay 2
tell application "Safari" to set the URL of the front document to "https://en.wikipedia.org/w/index.php? title=User:USERNAMEHERE/sandbox&action=edit" -- Goes back to sandbox and repeats the process
delay 2
end repeat
If you want to test this then put in your wikipedia username in the link and login into your account. Pretty much its a wikipedia bot that will just put stuff in my wikipedia sandbox

How to wait for webpage to fully load before proceeding script?

How do you wait for a webpage to fully load before proceeding the script?
I know you can use delay 4 if you would want it to wait 4 seconds but this is not safe enough.
In VBA you have a simple code that always works and it goes like this:
Dim x As String
x = "https://na6.salesforce.com/p/attach/NoteAttach?pid=" & Range("T34").Value & "&parentname=" & Range("T35").Value & "&retURL=%2F0018000000sKz8K%3Fpb0%3Dtrue"
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate (x)
IE.Visible = True
SetParent IE.Hwnd, Application.Hwnd
Do
DoEvents
Loop Until IE.READYSTATE = 4
What would be the equivalent of this on mac with safari for applescript?
I´ve seen many versions on the net but only workarounds similar to the delay or for a specify value to return or to count words on the page and so on.
I simply want the above version which is 100% perfect.
Thank you in advance:)
You can access the ready state of a page by calling "document.readyState" from either Safari or Chrome.
tell application "Safari"
if not (exists document 1) then reopen
tell current tab of window 1 to set URL to "https://stackoverflow.com/questions/24500011/how-to-wait-for-webpage-to-fully-load-before-proceeding-script"
set the_state to missing value
repeat until the_state is "complete"
set the_state to (do JavaScript "document.readyState" in document 1)
log "busy"
delay 0.2
end repeat
log "complete"
end tell
I do it in this way:
tell document 1 of application "Safari"
set URL to ""
set URL to "/slowly loading page/"
repeat until name is not "about:blank"
end repeat
end tell
Or, even easier:
tell front document of application "Safari"
set URL to "/slowly loading page/"
repeat until length of (source as text) is not 0
end repeat
end tell
Furthermore, there’s no need to do it without any delay:
repeat until length of (source as text) is not 0
delay 0.5
end repeat
Googled a bit and found this code that works for Safari Version 5.1.10 (6534.59.10) on Snow Leopard.
From http://macscripter.net/viewtopic.php?id=35176
tell application "Safari"
activate
repeat until SafariWindowHasLoaded(1) of me is true
end repeat
beep
end tell
on SafariWindowHasLoaded(inWindowIndex)
tell application "System Events" to ¬
tell application process "Safari"
set theStatusText to name of static text 1 of group 1 of window inWindowIndex as text
if theStatusText begins with "Contacting" or ¬
theStatusText begins with "Loading" or ¬
theStatusText begins with "Waiting" then
set theReturnValue to false
else
set theReturnValue to true
end if
end tell
return theReturnValue
end SafariWindowHasLoaded
Only problem I had was that this script was for an older version of Safari and the Status Bar element was in a different group than mine.
At http://hints.macworld.com/article.php?story=20071015132722688 it was suggested to change it to
static text 1 of group 2
and it worked!
I find getting the JavaScript "document.readyState" value the best way to determine if a page has finished loading, but that requires Safari to Developer > Allow JavaScript from Apple Events. Since that's is a security risk, I adjust Safari's preferences to enable it when it's needed, then disable it.
tell application "Safari" to open location ¬
"https://neeva.com/search?q=demon%20cats&c=Image&src=typedquery" -- random site
Wait_For_Safari()
--Feed cats and do other worthy things.
on Wait_For_Safari()
tell application "System Events" to set originatingApp to ¬
name of first application process where frontmost is true --in case we aren't executing from Safari
Allow_Apple_Events() --enable AllowJavaScriptFromAppleEvents so we can get JS's "document.readyState"
tell application "Safari"
set readyState to missing value
repeat until readyState is "complete" --wait for readyState = complete
set readyState to (do JavaScript "document.readyState" in document 1)
delay 0.2
end repeat
delay 0.2
end tell
Disallow_Apple_Events() --Disable AllowJavaScriptFromAppleEvents so our pants aren't down
tell application originatingApp to activate --return to wherever we started
end Wait_For_Safari
on Allow_Apple_Events()
do shell script "/usr/bin/defaults write com.apple.Safari AllowJavaScriptFromAppleEvents 1" --1 = enabled
end Allow_Apple_Events
on Disallow_Apple_Events()
do shell script "/usr/bin/defaults write com.apple.Safari AllowJavaScriptFromAppleEvents 0" --0 = disabled
end Disallow_Apple_Events

How to close safari tabs by url using applescript

I'm looking for a way to close specific tabs in safari by the url.
I would probably expand on something like this:
tell application "Safari"
repeat with t in tabs of windows
tell t
if name starts with "google.com" then close
end tell
end repeat
end tell
the problem here is that i haven't found a way how to get the url value of a tab and close them based on that.
You can get the URL from Safari based on the active tab.
tell application "Safari"
set w to first window
set t to current tab of w
display dialog (URL of t as string)
end tell
And then you could iterate over every tab/page like this :
tell application "Safari"
set windowCount to number of windows
repeat with x from 1 to windowCount
set tabCount to number of tabs in window x
repeat with y from 1 to tabCount
set thistab to tab y of window x
set foo to URL of thistab
if foo is not equal to "bar" then close thistab
end repeat
end repeat
end tell
Here is another method:
set closeURLs to {"http://www.yahoo.com", "http://www.apple.com"}
repeat with theURL in closeURLs
tell application "Safari" to close (every tab of every window whose URL contains (contents of theURL))
end repeat

Resources