Skip to content

Instantly share code, notes, and snippets.

@adminy
Last active January 18, 2023 04:49
Show Gist options
  • Select an option

  • Save adminy/5e80c40592b135e6d7fd8e6bd88c825a to your computer and use it in GitHub Desktop.

Select an option

Save adminy/5e80c40592b135e6d7fd8e6bd88c825a to your computer and use it in GitHub Desktop.
const randInt = (min, max) => Math.floor(Math.random() * (max - min + 1) + min) // min and max included
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
const followersElement = getFollowersElementWithUsername(getUsername())
followersElement.click()
function getUsername () {
const pageTitleElement = document.getElementsByTagName('h2')[0]
if (!pageTitleElement) throw new Error('No title to get username from')
return pageTitleElement.innerHTML
}
function getFollowersElementWithUsername (username) {
const followersElement = document.querySelectorAll('a[href="/' + username + '/following/"]')[0]
if (!followersElement) throw new Error('No followers element was found')
return followersElement
}
const friends = new Set(['user1', 'user2'])
const unfollows = {}
let tries = 0
let globalCount = 0
const hasMoreToLoad = ul => ul.childElementCount !== globalCount || ul.children[ul.childElementCount - 1].firstChild.getAttribute('data-visualcompletion') === 'loading-state'
const populateUnfollowsPool = () => {
const ul = document.querySelectorAll('ul')[1].firstChild
const lis = [...ul.querySelectorAll('li')]
.map(li => ({ button: li.querySelector('button'), name: (li.querySelector('a') || { href: '' }).href.split('/').slice(-2)[0] }))
.filter(({ button, name }) => button && button.textContent === 'Following' && name && !friends.has(name) && !unfollows[name])
lis.forEach(({ button, name }) => (unfollows[name] = { button, name }))
globalCount = ul.childElementCount
ul.children[globalCount - 1].scrollIntoView(true)
console.log('elements', globalCount, 'unfollows', Object.keys(unfollows).length, 'tries', tries)
setTimeout(() => hasMoreToLoad(ul) || tries++ < 3 ? populateUnfollowsPool() : finishedCollection(), randInt(848, 2004))
}
setTimeout(populateUnfollowsPool, 3000)
async function finishedCollection () {
console.log('!!! Collection Finished')
const toUnfollow = Object.values(unfollows)
const total = toUnfollow.length
for (let i = 0; i < total; i++) {
const { button, name } = toUnfollow[i]
button.scrollIntoView(true)
button.click()
await sleep(randInt(50, 200))
const unfollow = [...document.querySelectorAll('button')].find(button => button.textContent === 'Unfollow')
unfollow && unfollow.click()
console.log('Unfollowed ', name, (i / total * 100).toFixed(2), '%')
await sleep(i % 8 ? randInt(120, 800) : randInt(1, 10) * 60 * 1000)
}
}
@adminy

adminy commented Dec 19, 2021

Copy link
Copy Markdown
Author

Interesting. I've for some reason cannot access instagram from the computer anymore because password reset page does not work for me and I can't actually try the script anymore ...

It doesn't look like a serious problem though. Yeah, Instagram Will be slow ๐Ÿ˜… what's worse is their rate limiting is not quite easy to pin down anymore.

@adminy

adminy commented Dec 19, 2021

Copy link
Copy Markdown
Author

Since there is a lot of people having the same issue, I might look into the API itself to speed up this unfollow process.

@boxxxxy

boxxxxy commented Dec 19, 2021

Copy link
Copy Markdown

It's now unfollowing correctly after a few refreshes and script restarts, the api limit keep getting hit but after 5 mins it'll unfollow a couple more so it's ok!

@koolamusic

Copy link
Copy Markdown

Thanks for making this.

@mxxnshade

Copy link
Copy Markdown

keep getting
`Vev1H1eefJG.js?_nc_x=Ij3Wp8lg5Kz:59 ErrorUtils caught an error:

Cannot read properties of undefined (reading 'scrollIntoView')

Subsequent non-fatal errors won't be logged; see https://fburl.com/debugjs.`

@mikeknapp

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment