Given a map of a portion of the Facebook network, this script would try to identify groups of friends, based on the number of mutual friends shared between individuals. I guess you could call this a "poor man's k-means".

read more
on friendExtractionGivenan(id, type)
	
	
	if type is equal to "indirect" then
		tell application "Safari"
			set doc to front document
			set done_loading to false
			do JavaScript "
		window.location.assign('https://www.facebook.com/" & id & "?sk=friends&v=friends');
		" in doc
			delay 1
		end tell
	end if
	
	if type is equal to "direct" then
		tell application "Safari"
			set doc to front document
			set done_loading to false
			do JavaScript "
		window.location.assign('https://www.facebook.com/profile.php?id=" & id & "&sk=friends&v=friends');
		" in doc
			delay 1
		end tell
	end if
	
	
	delay 4
	
	tell application "Safari"
		repeat while done_loading is not equal to true
			set doc to front document
			set done_loading to do JavaScript "
			var done = false;
			 if (document.readyState=='complete'){
			 	done=true;
			}
			
			done;
				" in doc
			delay 1
		end repeat
	end tell
	
	
	
	tell application "Safari"
		set doc to front document
		set this_url to URL of doc
		set done_scrolling to false
		set filtered_URLs to {}
		set completed_once to false
		set erred_once to false
		
		
		repeat while done_scrolling is not equal to true
			try
				set done_scrolling to do JavaScript "
		
		var completed_once = " & completed_once & ";
		if(completed_once!=true){
		var done;
		var number_of_trys =0;
		}
    function scrollToBottom(){
      bottom = document.body.scrollHeight;
      current = window.innerHeight+ document.body.scrollTop;
	done = false;
      if((bottom-current) >0){
        window.scrollTo(0, bottom);
        setTimeout (scrollToBottom, 3500 ); //If the loading exceeds this timeout, a try will be used.
      }
	  else {
			done = true;	
			
	  }
    };
	if(completed_once!=true){
   	 scrollToBottom();
	}
	
	if(done==true&&number_of_trys<10){//This number changes the number of allowed timeouts
		done=false;
		number_of_trys++;
		setTimeout(scrollToBottom, 2000);
		//This number sets the allotted timeout length.
		//If the loading exceeds both the timeout above and this timeout, another try will be used immediately.
	}
	
	done;
	
    " in doc
				
				set completed_once to true
				delay 1.0
			on error
				
			end try
		end repeat
		
		
		
		set URLs to false
		repeat while URLs is equal to false
			set URLs to do JavaScript "

	   URLArray = [];

	      		allLinks = document.links;
		for (i = 0; i < allLinks.length; i++) {
		
			URLArray.push(allLinks[i].href);
		}
			URLArray;
			
	  " in doc
		end repeat
		return URLs
		
	end tell
	
end friendExtractionGivenan

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on extractionOfIDsFrom(unfiltered_links)
	set unfiltered to unfiltered_links
	set filtered to {}
	set direct_IDs to {}
	set indirect_IDs to {}
	set refined_IDs to {}
	set returned_IDs to {}
	repeat with x from 1 to count of items of unfiltered
		set n to item x of unfiltered
		if "=pb" is in n then
			if n is not in filtered then set end of filtered to n
		end if
	end repeat
	
	repeat with y from 1 to count of items of filtered
		set profile to item y of filtered
		
		if "profile.php?" is in profile then
			
			set end of direct_IDs to text ((offset of "=" in profile) + 1) thru ((offset of "&" in profile) - 1) of profile
			
		else
			set end of indirect_IDs to text 25 thru ((offset of "?" in profile) - 1) of profile
			
		end if
		
	end repeat
	
	return direct_IDs & indirect_IDs
	
end extractionOfIDsFrom


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on dataExtraction(startingID, id, type)
	
	
	tell application "Safari"
		set doc to front document
		set done_loading to false
		do JavaScript "
		window.location.assign('https://www.facebook.com/" & startingID & "?and=" & id & "');
		" in doc
		delay 1
	end tell
	
	
	
	
	tell application "Safari"
		repeat while done_loading is not equal to true
			set doc to front document
			set done_loading to do JavaScript "
			var done = false;
			 if (document.readyState=='complete'){
			 	done=true;
			}
			
			done;
				" in doc
			delay 1
		end repeat
	end tell
	
	
	delay 5
	tell application "Safari"
		set doc to front document
		set sourceCode to do JavaScript "
		document.documentElement.outerHTML;
		" in doc
		
	end tell
	
	set AppleScript's text item delimiters to ">Mutual Friends ("
	set refinedForPhotoCount to text items of sourceCode
	try
		set block to item 2 of refinedForPhotoCount
	on error
		delay 10
		tell application "Safari"
			set doc to front document
			set sourceCode to do JavaScript "
		document.documentElement.outerHTML;
		" in doc
		end tell
		set refinedForPhotoCount to text items of sourceCode
		set block to item 2 of refinedForPhotoCount --we're getting an error here
		
	end try
	
	
	set AppleScript's text item delimiters to ")"
	set refined to text items of block
	set blah to item 1 of refined
	
	--display dialog blah
	--return photoCount
	
	set numberOfMutualFriends to blah
	
	
	set weveGotAnError to false
	
	
	--https://graph.facebook.com/btaylor?fields=gender
	
	try
		set numberOfMutualFriends to numberOfMutualFriends as number
	on error
		set weveGotAnError to true
	end try
	
	if weveGotAnError is false then
		set returned to {id, numberOfMutualFriends}
	else
		set returned to {"false", "false"}
	end if
	
	return returned
	
end dataExtraction
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on storeIDs(user_id, friendPhotoCount, database1)
	
	tell application "Database Events"
		tell database1
			set node to make new record with properties {name:user_id}
			tell node
				make new field with properties {name:"Name", value:(item 1 of friendPhotoCount)}
				make new field with properties {name:"Number Of Mutual Friends", value:(item 2 of friendPhotoCount)}
			end tell
		end tell
	end tell
	save database1
end storeIDs

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on existsInDatabaseChecker(user_id, database1)
	tell application "Database Events"
		
		if record user_id of database1 exists then
			return true
		else
			return false
		end if
	end tell
end existsInDatabaseChecker
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
on exportToPlist(database1)
	
	tell application "System Events"
		set parent_dictionary to make new property list item with properties {kind:record}
		set the plistfile_path to ("Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:" & "FriendPhoto.plist")
		set plist to make new property list file with properties {contents:parent_dictionary, name:plistfile_path}
	end tell
	
	
	tell application "Database Events"
		repeat with y from 4 to count of records in database1
			set thefields to {}
			set currentRecordName to name of record y of database1
			
			repeat with x from 2 to count of fields of record currentRecordName in database1
				set end of thefields to value of field x of record currentRecordName of database1
			end repeat
			
			tell application "System Events"
				tell plist
					set node to make new property list item at end with properties {kind:record, name:currentRecordName}
					tell node
						
						set fieldID to item 1 of thefields
						make new property list item at end with properties {name:"Number of Friends", value:fieldID}
						set fieldID to item 2 of thefields
						make new property list item at end with properties {name:"Number of Photos", value:fieldID}
						
					end tell
				end tell
			end tell
			
		end repeat
	end tell
end exportToPlist
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

set theOutputFolder to POSIX path of "Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:"
set databaselocation to POSIX path of "Macintosh HD:Users:Puccio:Documents:My Documents:Scripts:Database:GroupPrediction.dbev"
tell application "Database Events"
	set database1 to database databaselocation
end tell

--exportToPlist(database1)

set processCancelled to false
set requestingStartingID to display dialog "Enter the subject whose friends you want to analyze" default answer "Monstermac77" with title "Analyze" buttons {"Indirect", "Direct", "Cancel"} default button "Indirect"
set button_pressed to the button returned of the result
if the button_pressed is "Direct" then
	set startingIDType to "Direct"
	
else if the button_pressed is "Indirect" then
	set startingIDType to "Indirect"
	
else
	set processCancelled to true
	
end if

display dialog "Would you like to use what's already in the database?" buttons {"Yes", "No"} default button "Yes"
if button returned of the result is "No" then
	set startingID to text returned of requestingStartingID
	set unfiltered_links to friendExtractionGivenan(startingID, startingIDType)
	set returnedIDs to extractionOfIDsFrom(unfiltered_links)
	
	set refinedIDs to {}
	repeat with b from 1 to count of returnedIDs
		set IDinterest to item b of returnedIDs
		set done to existsInDatabaseChecker(IDinterest, database1)
		--set done to false
		if done is false then
			set end of refinedIDs to IDinterest
		end if
		
	end repeat
	
	repeat with a from 1 to count of refinedIDs
		set IDofInterest to item a of refinedIDs
		set mutualFriendCount to dataExtraction(startingID, IDofInterest, "Indirect")
		storeIDs(IDofInterest, mutualFriendCount, database1)
	end repeat
	
else
	
end if

display dialog "What would you like to do?" buttons {"Export groups", "Analyze"} default button "Export groups"

if button returned of the result is "Export groups" then
	set outputText to ""
	tell application "Database Events"
		repeat with y from 1 to count of records in database1
			set thefields to {}
			set currentRecordName to name of record y of database1
			repeat with x from 2 to count of fields of record currentRecordName in database1
				set end of thefields to value of field x of record currentRecordName of database1
			end repeat
			
			
			
			
			
			set outputText to outputText & return & (item 1 of thefields) & "," & (item 2 of thefields)
			
			
			
		end repeat
	end tell
	tell application "TextEdit"
		activate
		make new document
		
		set text of document 1 to outputText as text
		--save document 1 in "/Users/Puccio/Desktop/hey.txt"
	end tell
else
	set frequencyTable to {}
	set mutualFriendTable to {}
	tell application "Database Events"
		repeat with y from 1 to count of records in database1
			set currentRecordName to name of record y of database1
			set numberOfMutualFriends to value of field 3 of record currentRecordName of database1
			set end of mutualFriendTable to {currentRecordName, numberOfMutualFriends}
		end repeat
		
		repeat with y from 1 to count of records in database1
			set currentRecordName to name of record y of database1
			set currentFrequency to 0
			repeat with x from 1 to count of records in database1
				set secondRecordName to name of record x of database1
				if x is not equal to y then
					if value of field 3 of record currentRecordName of database1 is equal to value of field 3 of record secondRecordName of database1 then
						set currentFrequency to currentFrequency + 1
					end if
				end if
			end repeat
			set end of frequencyTable to {currentRecordName, currentFrequency}
		end repeat
	end tell
	
	set currentHighestFrequency to 0
	set guyWithHighestFrequency to 0
	repeat with a from 1 to count of items in frequencyTable
		if item 2 of item a of frequencyTable is greater than currentHighestFrequency then
			set guyWithHighestFrequency to item 1 of item a of frequencyTable
		end if
	end repeat
	return guyWithHighestFrequency
	
	set theMostMutual to 0
	
	repeat with a from 1 to count of items in mutualFriendTable
		if item 1 of item a of mutualFriendTable is equal to guyWithHighestFrequency then
			set theMostMutual to item 2 of item a of mutualFriendTable
		end if
	end repeat
	
	set aGroup to {}
	set range to 0
	
	repeat with a from 1 to count of items in mutualFriendTable
		if item 2 of item a of mutualFriendTable is greater than theMostMutual - range and item 2 of item a of mutualFriendTable is less than theMostMutual + range or item 2 of item a of mutualFriendTable is equal to theMostMutual then
			set end of aGroup to {item 1 of item a of mutualFriendTable, item 2 of item a of mutualFriendTable}
		end if
		
	end repeat
	set range to range + 1
	
end if