셀레니움 활용 4

JOOYEUN SEO·2024년 10월 9일

100 Days of Python

목록 보기
52/76
post-thumbnail

🗂️ Day52 프로젝트: 인스타그램 팔로워 봇

나의 타겟과 같은 인스타그램 계정을 팔로우하는 사람들을 모두 자동으로 팔로우하는 봇

1. 인스타그램 계정 생성

🔍 유의 사항

  • 인스타그램 계정 생성(실습용 계정 생성 추천)
  • 프로젝트에 사용할 계정 선정(팔로워 수가 많은 계정 추천)
  • 대상 계정의 이름, 나의 이름, 나의 패스워드를 상수로 설정

2. 클래스 생성

🔍 유의 사항

  • InstaFollower 클래스 생성 후 외부에서 메소드들을 순서대로 호출
    • 인스타그램에 로그인하는 메소드
    • 대상 계정의 팔로워들을 찾는 메소드
    • 팔로우하는 메소드

3. 인스타그램 로그인

🔍 유의 사항

  • login() 메소드에 작성
  • 대상 계정 URL(instagram.com/계정 이름)으로 접속
  • 처리할 팝업
    • 크롬 알림 권한 요청
      • 해당 영역은 html 코드로 접근 불가
      • chrome_options에서 아예 안 뜨게 설정 가능
    • 페이스북 로그인 후 계정에 접근을 허가받는 팝업

4. 대상 계정의 팔로워 찾기

🔍 유의 사항

  • find_followers() 메소드에 작성
  • 팔로워 수를 클릭하여 해당 계정의 팔로워 확인
  • 팝업창에서 스크롤을 내려야 팔로워를 더 볼 수 있음 (처음 로딩 시 15명까지 보임)
    • 먼저 팝업에서 스크롤 가능한 목록 modal을 식별
      (모달: 웹에서 화면을 가리거나 그 위에 떠 있는 창을 의미)
    •  driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", modal)
      • 자바스크립트를 실행하는 메소드
      • 괄호 안은 팝업창(modal)의 스크롤을 맨 아래로 이동시키는 자바스크립트 명령어
      • arguments[0]
        • modal을 참조하는 매개변수로, 팝업 창을 스크롤 대상으로 지정
        • 자바스크립트에서 함수에 전달된 첫 번째 매개변수이기 때문에 인덱스 0
      • scrollTop
        • 스크롤 요소의 현재 스크롤 위치(0일 경우 맨 위에 있는 상태)
        • 해당 값은 스크롤된 픽셀 수로 측정(어디까지 내려갔는지 알 수 있음)
      • scrollHeight
        • 스크롤 가능한 전체 콘텐츠의 높이(현재 화면에 보이는 높이가 아님)

5. 팔로워 모두 팔로우하기

🔍 유의 사항

  • follow() 메소드에 작성
  • 팔로워 버튼들을 차례대로 클릭하는 코드
  • 다음 팔로워 버튼 클릭 전 1초 지연시간 추가하기
  • 이미 팔로워하는 계정일 경우 언팔로우할 지 묻는 팝업창이 떠서 팔로우 버튼을 가림
    • ElementClickInterceptedException 예외처리 임포트
    • 취소 버튼으로 팝업 닫고 계속하기

⌨️ main.py 최종

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
# 커스텀 예외 임포트
from selenium.common.exceptions import ElementClickInterceptedException

FB_EMAIL = "이메일"
FB_PASSWORD = "비밀번호"
SIMILAR_ACCOUNT = "cookat.magazine"

class InstaFollower:
    def __init__(self):
        chrome_options = webdriver.ChromeOptions()
        # 크롬 브라우저가 코드 종료 후에도 닫히지 않도록 설정
        chrome_options.add_experimental_option("detach", True)
        # 크롬 알림 권한 요청을 차단하는 설정(1은 허용, 2는 차단)
        chrome_options.add_experimental_option("prefs", {"profile.default_content_setting_values.notifications": 2})
        self.driver = webdriver.Chrome(options=chrome_options)

    def login(self):
        # 인스타그램 페이지로 이동
        self.driver.get("https://www.instagram.com")
        time.sleep(3)

        # 페이스북으로 로그인
        fb_login_button = self.driver.find_element(By.XPATH, '//*[@id="loginForm"]/div/div[5]/button')
        fb_login_button.click()
        time.sleep(2)

        email = self.driver.find_element(By.XPATH, '//*[@id="email"]')
        email.send_keys(FB_EMAIL)
        password = self.driver.find_element(By.XPATH, '//*[@id="pass"]')
        password.send_keys(FB_PASSWORD)
        password.send_keys(Keys.ENTER)
        time.sleep(3)

        # 페이스북 로그인 계속하기 팝업 닫기
        continue_login = self.driver.find_element(By.XPATH, '/html/body/div[3]/div[2]/div/div/form/div/div[1]/div[1]/div/div/div[3]/button[1]')
        continue_login.click()
        time.sleep(5)

    def find_followers(self):
        # 대상 계정으로 이동
        self.driver.get(f"https://www.instagram.com/{SIMILAR_ACCOUNT}")
        time.sleep(3)

        # 대상 계정의 팔로워 목록으로 이동
        followers = self.driver.find_element(By.XPATH, '/html/body/div[2]/div/div/div/div[2]/div/div/div[1]/div[2]/div/div[1]/section/main/div/header/section[3]/ul/li[2]/div/a')
        followers.click()
        time.sleep(5)

        # 팔로우 팝업에서 스크롤 (10번) 내리기
        modal = self.driver.find_element(By.XPATH, '/html/body/div[6]/div[2]/div/div/div[1]/div/div[2]/div/div/div/div/div[2]/div/div/div[3]')
        for i in range(10):
            self.driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", modal)
            time.sleep(2)

    def follow(self):
        follow_buttons = self.driver.find_elements(By.CSS_SELECTOR, '.xyi19xy.x1ccrb07 .x1dm5mii.x16mil14 .x9f619.xjbqb8w.x78zum5 button')
        for button in follow_buttons:
            try:
                button.click()
                time.sleep(1)
            except ElementClickInterceptedException:
                cancel_button = self.driver.find_element(By.XPATH, '/html/body/div[8]/div[1]/div/div[2]/div/div/div/div/div/div/button[2]')
                cancel_button.click()


bot = InstaFollower()
bot.login()
bot.find_followers()
bot.follow()

팔로우와 언팔로우를 짧은 간격으로 반복하면 경고 팝업이 뜨며 더 이상 팔로우를 할 수 없게 되기 떄문에 주의




▷ Angela Yu, [Python 부트캠프 : 100개의 프로젝트로 Python 개발 완전 정복], Udemy, https://www.udemy.com/course/best-100-days-python/?couponCode=ST3MT72524

0개의 댓글