Get Current Url from Browser in MACos

Get the URL of the frontmost tab from Chrome on OS X?

Since there is no applescript support the only way it can be done is through GUI scripting, I'm not sure how familiar you are with applescript but gui scripting is a bad practice to get into. so take this code with caution. it is also important that you have access for assistive devices ENABLED in your Universal Access preferences.

  tell application "Google Chrome"
activate
tell application "System Events"
tell application process "Google Chrome"
get value of text field 1 of tool bar 1 of window 1
end tell
end tell
end tell

MacOSX or AppleScript: get current URL from Firefox

Well, I have one solution now: I am reading it out of the current session store of Firefox. This works but it is always up to 10 seconds out-of-date.

Here is the code:
https://github.com/albertz/foreground_app_info/blob/master/mac/app-scripts/url%20of%20Firefox.py

How to copy the current active browser URL?

Code:

NSAppleScript *script= [[NSAppleScript alloc] initWithSource:@"tell application \"Safari\" to return URL of front document as string"];
NSDictionary *scriptError = nil;
NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&scriptError];
if(scriptError) {
NSLog(@"Error: %@",scriptError);
} else {
NSAppleEventDescriptor *unicode = [descriptor coerceToDescriptorType:typeUnicodeText];
NSData *data = [unicode data];
NSString *result = [[NSString alloc] initWithCharacters:(unichar*)[data bytes] length:[data length] / sizeof(unichar)];
NSLog(@"Result: %@",result);
}

Output:

Result: http://stackoverflow.com/questions/6111275/how-to-copy-the-current-active-browser-url/6111592#6111592

Get browser URL from third application

This isn't an easy answer but the good news is "yes, it's possible to do this without having to use AppleScript" and the bad news is "you'll have to use AppleScript to begin with".

Let me elaborate a bit: browser apps typically have an Applescript dictionary (which you can see by using the "Script Editor" application found in your /Applications/Utilities folder. Here's what the dictionary looks like for Google Chrome:Script Editor Dictionary for Google Chrome
You'll see I've found the "tab" class and in there you'll see the URL property.

So what you need to do is work up an AppleScript first to fetch the windows for the browser you're targeting. Then, when that's working, you need to convert the AppleScript to the underlying, raw AppleEvents (which is what AppleScripts compile to). Both AppleScripts and AppleEvents can be done in code.

The answer you're really looking for (e.g. "can I use some top secret API or send a URL from my code into some open port on my local machine to query the browser?") doesn't exist, as far as I know. AppleScript and AppleEvents are the longtime ways Apple provides to automate most apps and you'll need to leverage that.

If you decide to go ahead with using AppleScript and possibly converting them to AppleEvents, here's what I would do.

1) Find publicly available AppleScripts to do the work you want.

2) Convert the AppleScript to AppleEvents

3) Code up the AppleEvents.

For 1, here's a script that goes through every window in Safari, which I got from this tutorial:

tell application "Safari"

--Variables
set windowCount to number of windows
set docText to ""

--Repeat for Every Window
repeat with x from 1 to windowCount
set tabCount to number of tabs in window x

--Repeat for Every Tab in Current Window
repeat with y from 1 to tabCount
--Get Tab Name & URL
set tabName to name of tab y of window x
set tabURL to URL of tab y of window x
end repeat

end repeat
end tell

For step 2, I think you can use the Accessory View Pane in Script Editor to see the raw events and results produced.

For step 3, this ancient code that I wrote in C will get the URL for a browser window given a window ID.

OSStatus CreateTheAppleEventForGetURL( OSType appSignature, long windowid, char **retval) 
{
OSErr err = noErr;
AEAddressDesc targetAddress;
AEDescList replyDesc = { typeNull, nil };
AEKeyword keyword;
DescType desiredClass;
AEDesc replySingle, theOptionalAttributeDesc, theSeldDesc,theObjSpec,theThirdObjSpec,theSecondObjSpec,theFormDesc,theNullDesc;
AppleEvent theEvent, reply;
AEIdleUPP theIdleProc;
Boolean gotReply = false;
long errNumber=0;
long buffer;
Size actualSize;
char *result = NULL;

theIdleProc = NewAEIdleUPP((AEIdleProcPtr)&TheIdleFunction );
if( NULL != theIdleProc )
{
err = AECreateDesc( typeApplSignature, &appSignature, sizeof( appSignature ), &targetAddress );

if( noErr == err )
{
err = AECreateAppleEvent( 'core', 'getd', &targetAddress, kAutoGenerateReturnID, kAnyTransactionID, &theEvent );
buffer = 0x10000;
err = AECreateDesc('magn', &buffer, 4, &theOptionalAttributeDesc);
if( noErr == err )
{
err = AECreateDesc(typeNull, nil, 0, &theNullDesc);
desiredClass = 'cwin';
buffer = 'ID ';
err = AECreateDesc('enum',&buffer,4,&theFormDesc);
buffer = windowid;
err = AECreateDesc(typeLongInteger,&buffer,4,&theSeldDesc);
err = CreateObjSpecifier(desiredClass,&theNullDesc,'ID ',&theSeldDesc,true,&theThirdObjSpec);
buffer = 'docu';
err = AECreateDesc(typeType,&buffer,4,&theSeldDesc);
desiredClass = 'prop';
err = CreateObjSpecifier(desiredClass,&theThirdObjSpec,'prop',&theSeldDesc,true,&theSecondObjSpec);
buffer = 'prop';
err = AECreateDesc('enum',&buffer,4,&theFormDesc);
err = AECreateDesc(typeNull, nil, 0, &theObjSpec);
buffer = 'pURL';
err = AECreateDesc(typeType,&buffer,4,&theSeldDesc);
err = CreateObjSpecifier(desiredClass,&theSecondObjSpec,'prop',&theSeldDesc,true,&theObjSpec);
err = AEPutAttributeDesc(&theEvent,'csig',&theOptionalAttributeDesc);
err = AEPutParamDesc(&theEvent,keyDirectObject, &theObjSpec);
}
if( noErr == err )
{
err = AESend( &theEvent, &reply, kAEWaitReply + kAENeverInteract, kAENormalPriority, 120, theIdleProc, NULL );
if( noErr == err )
{
gotReply = true;
}
else
{
gotReply = false;
}
err = AEDisposeDesc(&theObjSpec);
err = AEDisposeDesc(&theOptionalAttributeDesc);
err = AEDisposeDesc(&theSeldDesc);
err = AEDisposeDesc(&theSecondObjSpec);
err = AEDisposeDesc(&theThirdObjSpec);
err = AEDisposeDesc(&theFormDesc);
err = AEDisposeDesc(&theNullDesc);
}
}
err = AEGetParamPtr(&reply, keyErrorNumber, typeLongInteger, NULL, &errNumber, sizeof(errNumber), &actualSize);
if(true == gotReply )
{
err = AEGetParamDesc( &reply, keyDirectObject, typeAEList, &replyDesc );

keyword = typeAEList;
err = AEGetNthDesc( &replyDesc, 1, typeUnicodeText, &keyword, &replySingle);

if( noErr == err)
{
OSStatus status;
Size theSize;
UnicodeMapping iUnicodeMapping;
UnicodeToTextInfo theInfo;
UniChar theName[512];
unsigned char crapola[512]; // a.k.a. a pstring

iUnicodeMapping.unicodeEncoding = kTextEncodingUnicodeDefault;
iUnicodeMapping.otherEncoding = kTextEncodingMacRoman;
iUnicodeMapping.mappingVersion = kUnicodeUseLatestMapping;
status = CreateUnicodeToTextInfo(&iUnicodeMapping,&theInfo);
theSize = AEGetDescDataSize(&replySingle);

err = AEGetDescData(&replySingle,&theName,512);
if( noErr == err)
{
err = ConvertFromUnicodeToPString(theInfo,theSize,theName,crapola);
if( noErr == err )
{
result = malloc( theSize * sizeof( char ));
if( NULL != result )
{
p2cstrcpy(result,crapola);
printf( "URL returned is %s\n", result);
}
}
}
status = DisposeUnicodeToTextInfo(&theInfo);
}
}
err = AEDisposeDesc( &targetAddress );
err = AEDisposeDesc( &replySingle );
DisposeAEIdleUPP( theIdleProc );
}
if( NULL != retval )
*retval = result;
return(err);
}

I'm sure it won't compile, since a number of Carbon API's have been updated and renamed since macOS 10.8, but you get the idea.

Hopefully this long essay helps you out!



Related Topics



Leave a reply



Submit