interaction with safari makes Safari CPU usage jump. Can I prevent it?

Hi there.

First I need to thank for the help with my first hobby ApplescriptObjc project I have received here. I had a very ambitious project given my experience but now I have a very stable and “feature complete” program. Without the help with a few but very important questions I would have been stuck.

But now I hope to streamline it a bit.

What I have is a program that queries a webpage, extract some information, do a lot of manipulation on it and store the results to a file. The program spent most of its time in a repeat block, half of the time inside another nested repeat block. As expected that give me a constant beachball. I dont´mind that for now because the main function of the program is to record information. I will look into adding a stop function so I can exit the program more gracefully later on.

But for some reason it also make Safaris CPU usage go through the ceiling. While the ASOC program itself use @ 15% CPU time, Safari jumps to 80-90% constant usage and the CPU temperature to 90-92 c (on my 2011 MBA). The program needs to run for 30-60 minutes at the time so I would really prefer it not to eat so many CPU cycles and generate so much heat. I have tried to ease up how often the program queries the web page but it doesn´t really seems to make a difference if I let it do it each second, each other second or five times per second.

My question is if there is something I can do to the structure of the program that would let Safari eat less cycles?

In pseudocode the program is as follows:

Hi,

do you really need Safari to parse the webpage?

You can retrieve the source text directly with cURL via NSTask or with NSURLConnection

Hey @melisen,

Why are you using System Events to drive Safari?

Safari is quite scriptable.

What information are you getting? It likely can be gotten more efficiently.

Very likely because I don´t know better :wink: System event also eats CPU time when my program i active.

I can’t give you the webpage I am getting the information from (behind login) but this is the general way I extract the data I need:

http://service.information.dk

tell application "System Events"
	tell process "Safari"
		try
			set tekst1 to value of static text of group 2 of group 5 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window "Abonnement | information.dk" of application process "Safari" of application "System Events"
		end try
	end tell
end tell
tekst1

This is perhaps more like the data I am trying to get as it also updates automatically:

http://www.betfair.com/exchange/tennis/event?id=27362353

tell application "System Events"
	tell process "Safari"
		
		tell group 1 of group 3 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window "Inglot/Mergea v Junaid/Shamasdin betting odds | betfair.com"
			tell table 1 of group 7
				set tekst2 to name of button of UI element 2 of row 3 as string
			end tell
		end tell
	end tell
end tell
tekst2

is there a better way to extract information from web pages like those?

StefanK: Thanks, I will look into it even if it looks very hard for me to use in my example.

So there isn´t really a way to make interaction between Applescript(ObjC) and Safari through the interface run more smoothly?

Hello @melisen,

Your tennis url produces a 404 Error. I need an actual working example to test.

try

http://www.betfair.com/exchange/tennis/event?id=27363753

and

tell application "System Events"
	tell process "Safari"
		
		tell group 1 of group 3 of UI element 1 of scroll area 1 of group 1 of group 1 of group 2 of window "J Donaldson v S Kozlov betting odds | Memphis Open 2015 | betfair.com
			tell table 1 of group 7
				set tekst2 to name of button of UI element 2 of row 3 as string
			end tell
		end tell
	end tell
end tell
tekst2

I wonder if it would make a difference if I used Webkit to display/access the webpages within the program (using Shanes sample code in ASOC Explored) ? Would I be able to address the elements in the web pages directly and reduce some overhead? And how would I address the elements within the program itself?

Hello @melisen,

That last example still isn’t working for me, so there probably is a difference in how our versions of Safari are set up.

It appears to me you’re gathering data from a webpage in Safari using System Events - yes?

It’s not an efficient method, however that doesn’t mean it’s the wrong method for your purpose.

In any case I’d look into alternatives before depending upon System Events.

Getting the text can produce parseable information, but it can also produce a really out of order mess. You have to try it and see.

tell application "Safari"
	tell front document
		set _text to its text
	end tell
end tell

Sometimes the source is easily parsed.

tell application "Safari"
	tell front document
		set _text to its source
	end tell
end tell

Sometimes you have to resort to using javascript to work the DOM (Document Object Model).

tell application "Safari"
	tell front document to set ¬
		{_name, _src} to {name, do JavaScript "window.document.documentElement.outerHTML"}
end tell

Personally I’d try to avoid using System Events if possible.

I suspect you could get much better results by using Smile.

http://www.satimage.fr/software/en/downloads/index.html

tell application "Smile"
	set webWin to make new web window with properties {path name:"http://macscripter.net/viewtopic.php?pid=178569#p178569"}
end tell

Smile has its own pause command smilepause which is rather more efficient than delay in AppleScript.

You can also run callJavaScript on a web window.

This may not fit with your ASObjC project, but it may be worth your while to know.

Sorry. I forgot to write the result.

This worked:

Of course first after I learned how to extract the data from the resulting text and rewrote large portion of the code (or more correctly threw large portions out and replaced it with something much simpler)

But it has halved the CPU load while even allowing me to set the update frequency to twice as often. And as an added bonus I can minimize the Safari windows. So my program is much better for it.

So thank you again :slight_smile: