AWK and WebView

I’m trying to bring up this website: www.ip-adress.com in Webview, and when I enter an ip address, in addition to the website opening up and showing me my ip address query in WebView, I want to return in another location only the city/state of that ip address query.

This website is apparently curl proof, so that’s why I’m opening the site up in my WebView browser.

I know AWK would help me bring back just the city/state of my ip query, but I don’t know enough about it to figure out how to write the code:

Here’s what I have:

on clicked theObject
	
	GetURL()
end clicked

on end editing theObject
	GetURL()
end end editing


on GetURL()
	
	tell window "main"
		
		set ipAddy to (the contents of text field "ipAddy") as text
		set theURL to "http://www.ip-adress.com" as text
		try
			set newString to (call method "stringByAddingPercentEscapesUsingEncoding:" of theURL with parameter 30)
			set URLWithString to call method "URLWithString:" of class "NSURL" with parameter newString
			set requestWithURL to call method "requestWithURL:" of class "NSURLRequest" with parameter URLWithString
			
			set mainFrame to call method "mainFrame" of object (view "browser")
			
			call method "loadRequest:" of mainFrame with parameter requestWithURL
		on error errmsg
			log errmsg
		end try

So I know I’d want to put a delay of 5 or so to give me time to enter the ip address in ip-address.com when WebView opens the site up. Can anyone help me out with the AWK command that will return information from the website brought up in WebView? I can’t figure out where to start, so if someone could show me how to at least use AWK to return anything from ip-adress.com in WebView, I can play around with the fields to have it return specifically the city state.

Hi George,

to parse the text is rather no problem, something like this

set sourceText to getTheText() 
set filteredText to paragraphs of (do shell script "echo " & quoted form of sourceText & " | awk '/FFFFFF/' | awk '/<td/'")
set theResult to {}
set TID to text item delimiters
repeat with i from 3 to 4
	set text item delimiters to ">"
	set tmp to text item 3 of item i of filteredText
	set text item delimiters to "<"
	set end of theResult to text item 1 of tmp
end repeat
set text item delimiters to ", "
set theResult to theResult as Unicode text
set text item delimiters to TID
display dialog theResult

the major problem is how to get the source text form the web view (the virtual getTheText() handler) ??

what about this … I find this on:

http://bbs.applescript.net/viewtopic.php?id=19891

   set rawHTML to text view "rawHtmlEdit" of scroll view "rawHtmlScroll" of window "rawHtmlWindow"
   set content of rawHTML to docContent
       
   set richText to view "webView" of window "editWindow"
   call method "setEditable:" of (richText) with parameters {true}
   call method "loadHTMLString:baseURL:" of (call method "mainFrame" of object richText) with parameter (docContent)
   

ScottyDelicious came up with that, and it seems like he’s trying to do something similar to what I’m doing. I played around with his code but couldn’t get it to work in my script, but seeing as to how I’m a complete noob, I might’ve been doing something stupid.

Is there a way to incorporate this to help me get the source text?

Hi,

this should work, BUT I have no idea how to wait until the page has been loaded.
I’ve added the javascript “document.readyState” command, but it’s not really working.
So you have to press the button as long as the page is loaded reliably.


on GetURL()
	tell window "main"
		set ipAddy to (the contents of text field "ipAddy") as text
		set theURL to "http://www.ip-adress.com" as text
		try
			set newString to (call method "stringByAddingPercentEscapesUsingEncoding:" of theURL with parameter 30)
			set URLWithString to call method "URLWithString:" of class "NSURL" with parameter newString
			set requestWithURL to call method "requestWithURL:" of class "NSURLRequest" with parameter URLWithString
			
			set mainFrame to call method "mainFrame" of object (view "browser")
			
			call method "loadRequest:" of mainFrame with parameter requestWithURL
			set scriptObject to (call method "windowScriptObject" of object (view "browser"))
			repeat
				call method "evaluateWebScript:" of scriptObject with parameter ("document.readyState")
				if result is "complete" then exit repeat
			end repeat
			set dom to (call method "DOMDocument" of mainFrame)
			set ele to (call method "documentElement" of dom)
			set theSource to (call method "outerHTML" of ele)
		on error errmsg
			log errmsg
		end try
	end tell
	
	set temp to ((path to temporary items as Unicode text) & "htmlTemp.txt") -- define tempfile
	set Ptemp to quoted form of POSIX path of temp
	do shell script "echo " & quoted form of theSource & " > " & Ptemp
	do shell script "textutil -format html -inputencoding iso-8859-1 -convert txt -encoding UTF-16 " & Ptemp -- convert html to txt
	set theText to paragraphs of (read file temp as Unicode text)
	do shell script "rm " & Ptemp -- delete tempfile
	set x to 50
	try
		repeat until item x of theText is "IP address state:"
			set x to x + 1
		end repeat
		set theResult to item (x + 3) of theText & ", " & item (x + 1) of theText
		display dialog theResult
	end try
end GetURL

Thank you StefanK, that worked!

I see what you mean about having to wait for the page to load though. So I have two choices, it seems.

(1). Create another script with another button that loads the page, and then execute the script you wrote.
or
(2). Use System Events to simulate the pressing of the “look up ip address” button on the web page itself.

I got (1). to work just fine, but I’d like to get this down to just one script, one button.

Here’s what my UIElement program said is the correct AppleScript action for pressing that “look up ip address” button on the website:

tell application “System Events”
click button “IP address / Host Lookup” of group 9 of UI element 1 of scroll area 1 of window “main”
tell application process “Test2” --“Test2” is the name of my program
end tell

I can’t figure out where to put that action though. It doesn’t seem like it can fit in my script.

Hi George & Stefan,

to wait for the webview finishing loading you need some simple Objective-C since unfortunately the Notifications cannot be accessed from AppleScript.
It might look like this:

[code]/* Controller.h */

#import <Cocoa/Cocoa.h>

@interface Controller : NSObject{
BOOL currentlyLoading;
}

-(BOOL)isLoading;

@end[/code]

[code]/* Controller.m */

#import “Controller.h”
#import <WebKit/WebKit.h>

@implementation Controller

  • (void)awakeFromNib{
    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
    [center addObserver:self
    selector:@selector(loadStarted)
    name:WebViewProgressStartedNotification
    object:nil];
    [center addObserver:self
    selector:@selector(loadEnded)
    name:WebViewProgressFinishedNotification
    object:nil];
    currentlyLoading = NO;
    }

  • (void) dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
    }

-(void)loadStarted{ currentlyLoading = YES; }

-(void)loadEnded{ currentlyLoading = NO; }

-(BOOL)isLoading{ return currentlyLoading; }

@end[/code]
Now to connect the Controller to our applescript we need to find a way to address the Controller object. I instantiated the Controller in Interface Builder and made it framleLoadDelegate of my webview (plz tell me when you need help for this step) …

then I can use the controller’s ‘isLoading’ method in the script:


        set loadstate to 0
        repeat until (loadstate is 1) -- wait until it has started loading
            delay 0.2
            set loadstate to (call method "isLoading" of (call method "frameLoadDelegate" of object (view "browser")))
        end repeat
        repeat while (loadstate is 1) -- wait while it is loading 
            delay 0.2
            set loadstate to (call method "isLoading" of (call method "frameLoadDelegate" of object (view "browser")))
        end repeat
        -- now it's finished and you can do further processing ... :-)

Hope that helps,

Dominik

I tell you :wink:

I know how to create a subclass but not to instantiate a existing one