What's So Fun About Fake?
I wrote about the Mac application “Fake”[1] awhile ago. From my very first use, I thought it was an incredibly clever tool. Fake is like a super-charged automator for Webkit. It makes automating interactions with webpages easy and simple. But why would I want to use Fake instead of Automator or curl or even a Python script? Here’s an example that I just started using.
If I want to add an affiliate link for a Mac or iOS app, I need to visit the Apple Link Maker page with my affiliate id as a get-parameter in the link. Then I need to choose iOS or Mac apps and type in the application name. I hit search and get back a list of apps. If I typed the name correctly, then the app I want will be on the top of the list.
I’m not done yet. I want the link, so I click the “App Link” to get a pop-over. I then select the link text and copy it. It’s kind of tedious and therefore, I haven’t used them much. What’s worse, all of the content only exists after the JavaScript has executed and added the content to the page. I can’t just submit a form and get a new page, I have to click the Submit button to generate the new document elements. That’s where most web scraping breaks.
This is a common problem with automating web-interactions. Automator, curl or python’s urllib will not have access to the content I want. That’s because developers are expecting a javascript engine to insert content into the DOM. Without a JS engine, the urllib2, Scrapy or BeautifulSoup functions are not useful.[2] That’s where something like Fake comes in handy.
Hello Fake
With Fake, I can automate the entire process. I build a Fake workflow much like I build an Automator workflow. Drag and drop actions and set variables. Fake has auto-discovery for form fields too. Just ctrl-drag from the action to the location on the page to auto-discover the element id. Fake will automatically determine the proper tag hierarchy to find it in the future.
Fake can also press buttons on the page. Now I’m getting somewhere. It can even extract the content I need from the JavaScript pop-over.
Here’s the workflow:
Macro Time
But how can I automate this process? Well, I kind of like Keyboard Maestro for this kind of stuff. Luckily, Fake has good AppleScript support. In my macro, KM pops up a form where I choose an app type[3] and type an app name to query. Next, an AppleScript is executed to launch the Fake workflow.
tell application “Fake”
activate
open "Macintosh HD 2:Dropbox:Development:Fake Workflows:getAppLink.fakeworkflow"
delay 1
run workflow
wait until done
close front document
quit
end tell
Fake can also run AppleScript so it can also get variables from Keyboard Maestro. Here’s the code from the first Fake action that grabs the input from the form:
set kmVarAppLink to ""
tell application “Keyboard Maestro Engine”
set kmVarAppName to (process tokens "%Variable%AppName%")
set kmVarAppType to (process tokens "%Variable%AppType%")
end tell
tell application “Fake”
set variable with name "appName" to kmVarAppName
set variable with name "appType" to kmVarAppType
end tell
Now fake has all of the information needed to load the page, populate the drop downs, click submit and then load the JavaScript pop-over. Finally, it copies the affiliate link to the clipboard for me.
The final workflow goes something like this:
<li>cmd-opt-M to open my Markdown palette of macros</li>
<li>Type C to choose the macro for appstore affiliate links</li>
<li>Fill out the popup form and click ok</li>
<li>wait for the alert that the macro is complete</li>
<li>paste the affiliate link</li>
Nice. I’m starting to play with Fake as more than just a way to probe web pages. It has some great potential. I haven’t even touched the more powerful actions that allow custom JS to be run against a page.
I would like to see more options to export a workflow to a stand-alone applet or script. Or perhaps a separate headless engine that could run independent of the application (like Keyboard Maestro). I’d also like integration with 1Password for autofill of passwords. I have a couple other ideas for automation that would require hard-coding login credentials and I’m not a fan of that.
<li id="fn:1">Affiliate Link <a class="reversefootnote" title="return to article" href="#fnref:1"> ↩</a></li>
<li id="fn:2">There are things like <a href="http://seleniumhq.org/projects/remote-control/">Selenium</a> that provide a JS engine to Python but I find it to be overly difficult and time consuming to use. I’m also not good at Python. So there’s that. <a class="reversefootnote" title="return to article" href="#fnref:2"> ↩</a></li>
<li id="fn:3">I find it interesting that the form value submitted for iOS apps is “software” and the form value for Mac apps is “macSoftware” <a class="reversefootnote" title="return to article" href="#fnref:3"> ↩</a></li>