Created
December 1, 2023 22:13
-
-
Save einarmagnus/b7c405614e53ad3583f1f235e99bcf24 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Get a list of your Facebook friends and how many friends in common you have. | |
This works in Chrome, Edge, and Safari, and probably most other browsers too. | |
It should work in Firefox around xmas 2023 when they too have | |
the `:has()` selector working (annouced release date is 17th of Dec) | |
- DON'T RUN SCRIPTS LIKE THIS FROM PEOPLE YOU DON'T KNOW OR TRUST. only do this if you know me, or can read code. | |
- go to https://www.facebook.com/me/friends | |
- press F12 (maybe fn+F12 if you have a fancy laptop), or right-click the page and chose "inspect". | |
- say yes, to any warnings that may be displayed. | |
- choose the console tab of the developer tools (top, maybe hidden behind a ">>" button | |
- copy all the code and paste it in the console. | |
- if you want to test it, you can change the limit (row 74) to something like 100, to get a result quicker. | |
just increase it and run the script again to get all your friends. | |
- it will take a while, as facebook only loads 8 contacts at a time, but after a couple | |
of minutes or so depending on how many friends you have, you should see a table in the console | |
and have data copied to your clipboard that you can paste in coda or excel or google sheets or wherever. | |
*/ | |
(async ({limit=Infinity, copy} = {}) => { | |
const $ = (a, b) => b ? a.querySelector(b) : document.querySelector(a); | |
const $$ = (a, b) => [...(b ? a.querySelectorAll(b) : document.querySelectorAll(a))]; | |
const friendsUrl = /^https?:\/\/www\.facebook\.com\/(?:[\w.]+\/|profile.php\?id=\d+&sk=)friends\/?$/; | |
if (!friendsUrl.test(window.location.href)) { | |
alert("Wrong page for this script, redirecting..."); | |
window.location = "/me/friends"; | |
} | |
let parent = $("[href$=friends_mutual]"); | |
while($$(parent, "[href$=friends_mutual]").length <= 1) | |
parent = parent.parentElement; | |
await new Promise((acc) => { | |
if ($$("[href$=photos_of]").length >= 1) { | |
// the phots section has loaded below the friends list | |
return acc(); | |
} | |
let loadedFriends = 0; | |
const observer = new ResizeObserver(entries => { | |
const freshLoadedFriends = $$(parent, "a[href] img").length; | |
if (freshLoadedFriends === loadedFriends || freshLoadedFriends > limit) { | |
if (freshLoadedFriends === loadedFriends) { | |
console.log("All friends loaded!") | |
} else { | |
console.log("Limit reached!") | |
} | |
observer.disconnect(); | |
return acc(); | |
} | |
loadedFriends = freshLoadedFriends; | |
console.log(`${freshLoadedFriends} friends loaded`); | |
window.scrollTo(0, document.body.scrollHeight); | |
}) | |
observer.observe($('body')) | |
}); | |
const friends = $$(parent, ":scope > div") | |
.map(n => $$(n, "a:not(:has(img))").map(a => a.innerText)) | |
.filter(([name, count]) => (name || count) !== undefined) | |
.map(([name, count]) => [name.trim(), parseInt(count??-1)]) | |
.sort(([,a], [,b]) => b - a); | |
return { | |
friends, | |
csv: (separator=",") => | |
friends.map(([name, count]) => | |
`${name}${separator}${count === -1 ? "" : count}` | |
).join("\n"), | |
copy | |
}; | |
})({limit: 5000, copy}).then(({friends, csv, copy}) => { | |
copy(csv('\t')); | |
console.table(friends); | |
console.log("data copied to clipboard") | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment