Como a Billie Eilish colocou todos os seguidores no Close Friends do Instagram?
Era uma quinta-feira, dia 04/04/2024, quando diversos seguidores da cantora Billie Eilish ficaram surpresos ao serem adicionados nos melhores amigos do Instagram dela. De início, achei que fosse alguma brincadeira, porém, fui pesquisar sobre isso e encontrei a seguinte matéria:
Fiquei pensando como ela poderia ter feito isso, e após uma pesquisa rápida, percebi algumas coisas estranhas:
- Apesar de ter milhões de seguidores, o perfil não seguia ninguém;
- Nem todos os seguidores foram adicionados ao mesmo tempo;
- A API do Instagram não lista a opção de adicionar alguém ao close, apenas para:
- Obter e gerenciar fotos, vídeos e stories publicados
- Obter dados básicos sobre contas de criadores de conteúdo e outras contas comerciais
- Moderar comentários e as respectivas respostas
- Mensurar a interação com mídias e perfis
- Encontrar mídias com hashtags
- Encontrar @menções
- Publicação de conteúdo
Ou seja, ela não adicionou todos de uma vez; foi um processo procedural (de seguidor em seguidor); a API já não libera a funcionalidade de adicionar alguém que você segue no close friends, imagina alguém que você não segue.
Essas questões me deixaram pensativo acerca de como ela poderia ter feito isso, talvez contratou uma equipe pra fazer o processo manualmente? talvez contratou um desenvolvedor pra implementar isso (o que acredito que tenha acontecido).
Mas se ela contratou um desenvolvedor, como ele fez isso? E, caso estejam curiosos, infelizmente, não faço ideia de como isso foi feito 😅
Por isso, tive a ideia de trazer essa discussão aqui pro TabNews, como vocês acham que ela fez isso? Contratou um desenvolvedor ou foi no estilo da Amazon?
passou a mao no telefone e falou com alguem que trabalha com o tio Zuck tambem pode ser uma opção, pq não?
Muito provavelmente foi feito utilizando um RPA desenvolvido ou comprado e parametrizado (mais provavel este ultimo). Se voce nao conhece o que é RPA (Robot Process Automation), basicamente voce grava uma execucao da sua tela e deixa o Robo executando aquela gravacao varias vezes. Por exemplo, se ela conseguiu exportar os seguidores para um arquivo ela pode passar esse arquivo para o Robo e ele vai executar o mesmo script dando loop no arquivo. Caso ela nao pode exportar esta lista, ela pode ter um passo adicional dando loop na tela de seguidores. Na pratica o RPA vai simular uma execucao humana, entao nao depende de API e o sistema dificilmente identifica que esta sendo processado por RPA. Normalmente captcha e outras tecnicas podem tentar barrar este tipo de execucao, mas que tambem em alguns casos podem ser superados.
Este conceito é muito utilizado em meio corporativo para automatizar tarefas repetitivas e deixar os empregados trabalhando no que exige acao humana.
- Uipath
- Automation Anywhere
- iRPA
Sao exemplos de ferramentas de mercado que possuem itens adicionais para empresa como orquestracao e etc.
No entando voce pode escrever sua automacao facilmente com Python e outras linguagens.
Foi um acordo feito com a META, foi fácil e rápido. De certo só deram um UPDATE no banco de dados, rapidinho e super eficiente.
Teve um site que noticiou que foi feito esse acordo... só não tô muito afim de ir procurar agora kkkkk
segue em python como pode ser feito.
import sys
import csv
import time
import pickle
import random # Importando o módulo random
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException, WebDriverException
COOKIES_FILE = "instagram_cookies.pkl"
INDEX_FILE = "index.txt" # Arquivo para armazenar o índice atual
def save_index(index):
"""
Salva o índice (linha atual) no arquivo index.txt.
"""
with open(INDEX_FILE, "w") as f:
f.write(str(index))
print(f"[INFO] Índice {index} salvo em {INDEX_FILE}.")
def load_index():
"""
Lê o índice salvo no arquivo index.txt.
Retorna 0 se o arquivo não existir ou não puder ser lido.
"""
if not os.path.exists(INDEX_FILE):
return 0
with open(INDEX_FILE, "r") as f:
try:
return int(f.read().strip())
except ValueError:
return 0
def is_logged_in(driver, username):
"""
Verifica se estamos logados procurando o link para o perfil do usuário (ex: /username/).
"""
time.sleep(random.uniform(2, 4)) # Pausa aleatória para o DOM carregar
try:
driver.find_element(By.XPATH, f'//a[@href="/{username}/"]')
return True
except NoSuchElementException:
return False
def save_cookies(driver, path):
"""
Salva as cookies atuais do navegador em um arquivo .pkl.
"""
with open(path, "wb") as file:
pickle.dump(driver.get_cookies(), file)
print(f"[INFO] Cookies salvos em {path}.")
def load_cookies(driver, path):
"""
Carrega cookies de arquivo e as adiciona ao driver.
Retorna True se as cookies foram carregadas, False caso contrário.
"""
if not os.path.exists(path):
print(f"[INFO] Arquivo de cookies '{path}' não existe. Ignorando.")
return False
print(f"[INFO] Carregando cookies de {path} (antes de visitar o Instagram)...")
with open(path, "rb") as file:
cookies = pickle.load(file)
for cookie in cookies:
# Ajuste do domínio para garantir que elas sejam aceitas
cookie['domain'] = '.instagram.com'
# Remove 'sameSite' se existir (alguns drivers não aceitam)
cookie.pop('sameSite', None)
cookie_name = cookie.get('name')
try:
driver.add_cookie(cookie)
driver.refresh()
print(f"[INFO] Cookie '{cookie_name}' adicionado.")
time.sleep(1)
except Exception as e:
print(f"[WARN] Falha ao adicionar cookie '{cookie_name}': {e}")
print(f"[INFO] Cookies carregadas de {path}.")
return True
def login_instagram(driver, username, password):
"""
Faz login no Instagram de forma 'tradicional' (usuário e senha).
"""
print("[INFO] Realizando login manual...")
try:
username_input = driver.find_element(By.NAME, "username")
password_input = driver.find_element(By.NAME, "password")
username_input.send_keys(username)
password_input.send_keys(password)
password_input.send_keys(Keys.RETURN)
time.sleep(random.uniform(4, 6)) # Pausa aleatória para aguardar o carregamento
print("[INFO] Login realizado com sucesso.")
save_cookies(driver, COOKIES_FILE)
except NoSuchElementException as e:
print(f"[ERRO] Elemento de login não encontrado: {e}")
return False
except WebDriverException as e:
print(f"[ERRO] Erro ao tentar enviar dados de login: {e}")
return False
return True
def cleanup(driver):
"""
Limpeza após falha, garantindo que o driver seja fechado.
"""
print("[INFO] Limpando e fechando o navegador...")
driver.quit()
def add_close_friends_from_csv(driver, csv_file, start_index):
"""
Lê a SEGUNDA coluna do arquivo CSV e, para cada usuário,
pesquisa o nome no input de busca e tenta marcar como Close Friend.
"""
# 1. Acessar a página de "Close Friends"
driver.get("https://www.instagram.com/accounts/close_friends/")
time.sleep(random.uniform(8, 12)) # Pausa aleatória
pathFile = os.path.join(os.getcwd(), csv_file)
with open(pathFile, "r") as f:
reader = csv.reader(f, delimiter=";")
index = 0
print("[INFO] Iniciando leitura do arquivo CSV...")
for row in reader:
if index < start_index:
index += 1
continue # Pula até a linha inicial
if len(row) < 2:
continue # linha sem ao menos 2 colunas
# use separator ; to get second column
user_to_add = row[1].strip()
if not user_to_add:
continue
search_input = driver.find_element(By.XPATH, '//input[@placeholder="Pesquisar"]')
search_input.clear() # Limpar qualquer texto existente
search_input.send_keys(user_to_add)
time.sleep(random.uniform(5, 8)) # Pausa aleatória
user_cards = driver.find_elements(
By.XPATH,
'//div[@data-bloks-name="bk.components.Flexbox" '
'and contains(@class,"wbloks_1") and @role="button"]'
)
user_card = user_cards[0] if user_cards else None
if (user_card == None):
print(f"[INFO] Não encontrei o usuário {user_to_add} na busca.")
continue
# 3. Verificar se o usuário está visível na lista de resultados
try:
try:
user_card.find_element(
By.XPATH, './/div[contains(@style, "circle-check__filled__24")]'
)
print(f"[INFO] {user_to_add} já é Close Friend, passando para o próximo.")
continue # Já está marcado, passe para o próximo
except NoSuchElementException:
# 4. Marcar o usuário como Close Friend
user_card.click()
print(f"[INFO] {user_to_add} adicionado aos Close Friends.")
time.sleep(random.uniform(2, 3)) # Pausa aleatória
except NoSuchElementException:
print(f"[INFO] Não encontrei o usuário {user_to_add} na busca.")
time.sleep(random.uniform(2, 4)) # Pausa aleatória
# Salvar o índice após cada iteração
save_index(index)
index += 1
def main(args):
"""
Uso:
python script.py SEU_USUARIO SUA_SENHA
"""
username = args[0]
password = args[1]
# Carregar o índice de onde o script deve começar
start_index = load_index()
print(f"[INFO] Iniciando de onde parou, linha {start_index + 1}.")
print("[INFO] Iniciando o WebDriver...")
driver = webdriver.Chrome()
# 1) Carregar cookies antes de abrir o Instagram
print("[INFO] Acessando página 'about:blank' para inserir cookies primeiro...")
driver.get("about:blank")
if not load_cookies(driver, COOKIES_FILE):
print("[INFO] Cookies não carregados, tentando login manual.")
# 2) Agora sim, acessar Instagram
print("[INFO] Indo para https://www.instagram.com/")
driver.get("https://www.instagram.com/")
time.sleep(random.uniform(1, 2)) # Pausa aleatória para login
# 3) Verifica se as cookies nos deixaram logados
if is_logged_in(driver, username):
print("[INFO] Já estamos logados via cookies (sem necessidade de login).")
else:
print("[INFO] Não foi possível usar cookies para login. Fazendo login manual.")
if not login_instagram(driver, username, password):
print("[ERRO] Falha no login. Verifique credenciais ou bloqueios.")
cleanup(driver)
return
# 4) Ler e adicionar Close Friends
add_close_friends_from_csv(driver, "lista.csv", start_index)
print("[INFO] Finalizando em 5s...")
time.sleep(random.uniform(4, 6)) # Pausa aleatória
driver.quit()
if __name__ == "__main__":
# Exemplo:
# python script.py SEU_USUARIO SUA_SENHA
main(sys.argv[1:])
Também fiquei muito curioso quando minha namorada acabou me trazendo essa informação.
Acabei debatendo com ela sobre, e eu que não seguia fui lá seguir para testar. Fui adicionado imediatamente ao CloseFriends dela, porém batendo com o horário do EUA ja era madrugada, então não fazia muito sentido ser alguém físico por trás, nem humanamente possível essa resposta tão rápida.
Pensei em diversas maneiras e acredito que seja algo próximo ao que o pessoal usa para votar em programas como Big Brother, ou de votação em geral, um robô.
Enfim, dormi com a dúvida na cabeça kkk, porém tenho q admitir que foi uma ideia genial.
Eu especulo que houve um acordo da equipe dela com a Meta pra liberar a funcionalidade apenas para o perfil dela fazer a ação.
Vi uma galera pedindo isso como extensão uma vez, pode ser uma boa ideia de projeto lateral. O que teve de gente querendo copiar essa jogada de marketing é brincadeira.