Extract Safari Titles and URLs via AppleScript and JXA
This article explains how to automate the extraction of webpage titles and URLs from all open windows and tabs in the Safari web browser on macOS. It provides ready-to-use scripts and clear explanations for both AppleScript and JavaScript for Automation (JXA), demonstrating how to iterate through browser elements to retrieve their data efficiently.
Using AppleScript
To extract data from Safari using AppleScript, you must communicate
with the application's scripting dictionary. Safari organizes its
elements hierarchically: the application contains windows,
and each window contains tabs. Each tab has a
name property (the title) and a URL
property.
Here is the AppleScript to iterate through every window and tab:
set extractedData to ""
tell application "Safari"
set windowList to every window
repeat with aWindow in windowList
-- Ensure the window actually supports tabs (ignores preference panes)
if exists tabs of aWindow then
set tabList to every tab of aWindow
repeat with aTab in tabList
set tabTitle to name of aTab
set tabURL to URL of aTab
set extractedData to extractedData & tabTitle & " | " & tabURL & linefeed
end repeat
end if
end repeat
end tell
return extractedData
How the AppleScript Works
tell application "Safari": Directs the script's commands to the Safari browser.repeat with aWindow in windowList: Starts the outer loop, iterating through all open Safari windows.if exists tabs of aWindow: Prevents errors by ensuring the current window is a standard browser window and not a dialog box or settings window.repeat with aTab in tabList: Starts the inner loop, going through each tab inside the current window.name of aTabandURL of aTab: Extracts the title and web address, appending them to theextractedDatatext variable, separated by a line break.
Using JavaScript for Automation (JXA)
JavaScript for Automation (JXA) provides an alternative way to interact with macOS applications using standard JavaScript syntax. In JXA, properties are accessed as methods (using parentheses) rather than simple values.
Here is the JXA script to achieve the same result:
const safari = Application("Safari");
let extractedData = [];
const windows = safari.windows();
for (let i = 0; i < windows.length; i++) {
const currentWindow = windows[i];
// Check if the window has valid tabs
let tabs;
try {
tabs = currentWindow.tabs();
} catch (e) {
continue;
}
for (let j = 0; j < tabs.length; j++) {
const currentTab = tabs[j];
const tabTitle = currentTab.name();
const tabURL = currentTab.url();
extractedData.push(`${tabTitle} | ${tabURL}`);
}
}
extractedData.join("\n");How the JXA Script Works
Application("Safari"): Instantiates the Safari application object.safari.windows(): Calls thewindowsmethod to return an array of open window objects.try...catchblock: Safely attempts to get thetabs()array for the current window. If a non-browser window is encountered, it skips to the next iteration.currentTab.name()andcurrentTab.url(): Calls the methods on the tab object to retrieve the title and URL strings.extractedData.join("\n"): Combines all elements of the array into a single string separated by new lines and returns the final output.
How to Run the Scripts
You can execute both of these scripts natively on macOS using two methods:
Method 1: Script Editor
- Open the Script Editor application (located in
/Applications/Utilities/). - Click New Document.
- Set the language dropdown in the top-left corner (below the record buttons) to either AppleScript or JavaScript.
- Paste the corresponding code into the editor.
- Click the Play (Run) button in the toolbar. The extracted titles and URLs will appear in the Result pane at the bottom of the window.
Method 2: Terminal (Command Line)
You can run these scripts directly from the macOS Terminal using the
osascript command.
To run the AppleScript file from the terminal:
osascript path/to/script.scptTo run the JXA file from the terminal, you must include the
-l JavaScript flag:
osascript -l JavaScript path/to/script.js