DEV

[Python]인스타그램 좋아요 봇(오고곡)

easthyeok 2023. 5. 2. 01:19
Ogogok_v250315.zip
19.82MB

하루종일 인스타 피드 좋아요를

누르고 있는 지인에게
오곡 쌀 한 톨만큼이라도 도움을🙏

겸사겸사 파이썬 공부할 겸 만들어본 인스타 자동 좋아요 봇이다
2023.05.02 - v1.0
2023.07.29 - v1.3 - 나중에하기,좋아요 버튼수정
2025.03.16 - v250315 - 다 버리고 피드좋아요만 살림 
*나중에 하기 버튼은 수동클릭필요. 아무리해도 잘 안됨

[사용법]

1. 피드 좋아요

  • 최신 피드에 대한 좋아요 수 지정(ex: 100 입력 시 최신피드 100개 좋아요 누른 후 종료)
  • 좋아요 수 지정 후 좋아요♥ 버튼 클릭 !
  • 피드좋아요만 사용할 경우 해시태그,좋아요 수 입력칸은 공백으로 냅두기 !!!!

2. 해시태그 좋아요

  • 해시태그 : 검색할 해시태그 지정 (ex: 오운완)
  • 좋아요 수 : 검색한 해시태그에 대한 게시물 좋아요 수
  • 해시태그 및 좋아요 수 지정 후 해시태그🙏🙏 버튼 클릭 !
  • 인스타 로그인 -> 지정한 해시태그로 검색 -> 좋아요 수 만큼 게시글 좋아요 수행
  •  해시태그 좋아요만 사용할 경우 피드좋아요 수 입력칸은 공백으로 냅두기 !!!!

3. 피드 태그 좋아요

  • 피드 좋아요해시태그 좋아요를 둘 다 사용할 경우
  • 모든칸을 다 채우고 해당버튼 클릭 시 피드좋아요 수행 후 해시태그 좋아요까지 모두 수행

4. 동작확인

피드 좋아요 완료 ~
해시태그 좋아요 완료 ~
사전에 정의된 단어로 필터링된 광고 발견 시

※ 너무 많은양의 좋아요는 인스타에서 봇으로 판단하여 밴당할수 있으니 요령껏 적당한 값을
입력하여 사용하자

p.s 테스트해본 결과 100개 내외가 적당한것 같다

[코드 리뷰]

1. 사용한 모듈

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import unicodedata
from selenium.webdriver.common.by import By
import inspect, os, platform, time, random
import chromedriver_autoinstaller
from tkinter import *
import tkinter as tk
import datetime
  • from selenium import webdriver : 크롬 웹드라이버 구동 
  • from selenium.webdriver.common.keys import Keys : 웹 페이지 내에서 키보드 입력
  • import unicodedata : 한글을 str로 인식할 경우 자음과 모음으로 분리되어 있다 이를 합치기위한 모듈 
  • from selenium.webdriver.common.by import By : 웹페이지내에 element를 검색
  • import inspect, os, platform, time, random : 시간,랜덤,os정보,구문오류,사용중인플랫폼등등 정보출력
  • import chromedriver_autoinstaller : Chrome 브라우저용 드라이버를 자동으로 설치해주는 모듈
  • from tkinter import * :  GUI 프로그래밍을 위한 모듈
  • import tkinter as tk : 별칭지정 
  • import datetime : 시간출력을 위한 모듈 

2. 광고 필터링(detect_ad)

def detect_ad():
    ad_list = ['팔로워', '재테크',  '부업', '고수입', '수입', '최저가', '연봉', '순수익', '금액', '입금']
    article = driver.find_elements(By.XPATH, '//article//div[1]/span')
    for texts in article:
        text = unicodedata.normalize('NFC',texts.get_attribute('innerText'))
        for ad in ad_list:
            if text.find(ad) == -1 :
                continue
            else :
                print(f'광고 발견. 발견된 광고단어 : {ad}')
                lbox.insert(END, f'광고 발견. 발견된 광고단어 : {ad}')
                lbox.update()
                lbox.see(END)
                return True
  • ad_list : 필터링할 광고단어 정의
  • article : 인스타그램 게시물에서 텍스트가져옴
  • text : article을 통해 가져온 텍스트를 unicodedata모듈을 통해 자음과 모음을 합치는 정규화 수행
  • for 문 : 광고에 해당하는 단어들이 포함되어있는지 확인 , 없으면 continue ~ 

3. 로그인(login)

def login():
    chrome_ver = chromedriver_autoinstaller.get_chrome_version().split('.')[0]
    driver_path = f'./{chrome_ver}/chromedriver.exe'
    if os.path.exists(driver_path):
        print(f"chrom driver is insatlled: {driver_path}")
    else:
        print(f"install the chrome driver(ver: {chrome_ver})")
        chromedriver_autoinstaller.install(True)

    insta_id = login_id.get()
    insta_pw = login_pw.get()
    options = webdriver.ChromeOptions()
    options.add_experimental_option("excludeSwitches", ["enable-logging"])
    global driver
    driver = webdriver.Chrome(driver_path,options=options)
    driver.get('https://www.instagram.com/?hl=ko')
    print('로그인중....')
    time.sleep(4)


    id_input = driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[1]/div/label')
    id_input.click()
    id_input.send_keys(insta_id)

    pw_input = driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[2]/div/label')
    pw_input.click()
    pw_input.send_keys(insta_pw)
    time.sleep(2)

    pw_input.send_keys(Keys.ENTER)
    time.sleep(5)

    try:
        btn_later1 = driver.find_element_by_class_name('_acan._acao._acas')
        btn_later1.click()
        time.sleep(3)
    except:
        pass

    try:
        btn_later2 = driver.find_element_by_class_name('_a9--._a9_1')
        btn_later2.click()
        time.sleep(3)
    except:
        pass
    try:
        driver.find_element(By.XPATH, '//div[text() = "새 게시물"] //ancestor :: button').click()
    except:
        pass
  • chromedriver를 통해 PC에 설치된 크롬버전 확인 후 드라이버 설치 
  •  options.add_experimental_option("excludeSwitches", ["enable-logging"]) : 불필요한 에러메시지 출력 X

  • btn_later1 : 로그인 저장 정보 "나중에 하기" 클릭

btn_later2 : 알림 설정 "나중에 하기" 클릭

4. hashtag

def hashtag():
    login()
    insta_tag = hashtag_entry.get()
    like_cnt = hashtaglike_entry.get()
    like_cnt = int(like_cnt)

    time.sleep(15)
    driver.get('https://www.instagram.com/explore/tags/{}/'.format(insta_tag))
    time.sleep(random.uniform(4.0, 8.0))
    driver.implicitly_wait(15)

    new_feed = driver.find_elements(By.XPATH, '//article//img //ancestor :: div[2]')[9]
    new_feed.click()

    numoflike = 0
    for i in range(like_cnt):
        time.sleep(random.uniform(4.0, 6.0))
        driver.implicitly_wait(15)
        span = driver.find_element(By.XPATH, '//*[@aria-label="좋아요" or @aria-label="좋아요 취소"]//ancestor :: span[2]')
        like_btn = span.find_element(By.TAG_NAME, 'button')
        btn_svg = like_btn.find_element(By.TAG_NAME, 'svg')
        svg = btn_svg.get_attribute('aria-label')
        if detect_ad() == True:
            next_feed_xpath = driver.find_element(By.XPATH,
                                                  '//*[@aria-label="다음" and @height="16"]//ancestor :: div[2]')
            next_feed = next_feed_xpath.find_element(By.TAG_NAME,
                                                     'button')
            next_feed.click()
            driver.implicitly_wait(10)
        else:
            if svg == '좋아요':
                like_btn.click()
                numoflike += 1
                print('좋아요를 {}번째 눌렀습니다.'.format(numoflike))
                lbox.insert(END, f'좋아요를 {numoflike}개 누름')
                lbox.update()
                lbox.see(END)
                time.sleep(random.uniform(20.0, 40.0))
            else:
                print('이미 작업한 피드입니다.')
                time.sleep(random.uniform(4.0, 6.0))

            if i < like_cnt - 1:
                next_feed_xpath = driver.find_element(By.XPATH,
                                                      '//*[@aria-label="다음" and @height="16"]//ancestor :: div[2]')
                next_feed = next_feed_xpath.find_element(By.TAG_NAME,
                                                         'button')
                next_feed.click()
                time.sleep(random.uniform(4.0, 6.0))
                driver.implicitly_wait(15)

    print("좋아요 작업이 끝났습니다. 프로그램을 종료합니다.")
    lbox.insert(END, f'좋아요를 {numoflike}개 누르고 작업을 종료합니닷!!!!!!!!')
  • 로그인 → 해쉬태그 → #오운완 → 게시글 클릭 → 좋아요 누르기 → 다음게시글 → 반복
  • new_feed = driver.find_elements(By.XPATH, '//article//img //ancestor :: div[2]')[9] : 최신 게시물중 10번째 게시물부터 클릭하게설정 -> 1~9번째 게시물은 광고가 너무많다
  • span : "좋아요" 또는 "좋아요 취소" 버튼요소를 찾아온다
  • like_btn : 좋아요버튼 / btn_svg -> svg : 좋아요 버튼에 대한 속성값(좋아요,좋아요 취소) 
  • svg의 값이 "좋아요 취소"일 경우 이미 좋아요를 작업한 게시글임
  • if dected ad() : 광고필터링함수를 호출하여 광고단어 발견 시 다음게시글로 바로 이동
  • if svg : svg가 "좋아요" 일 경우 좋아요 버튼 누르고 20~40초 대기, svg가 "좋아요"가 아닐경우 다음게시글로 이동
  • like_cnt : 작업 할 좋아요 수 
  • if i < like_cnt - 1: "좋아요" 버튼 누르고 다음 게시글로 이동

5. 피드 좋아요(feed) 

def feed():
    login()
    feed_button = feed_entry.get()
    following_stopnum = int(feed_button)
    following_likenum = 0
    # newwin = Tk()
    while following_likenum < following_stopnum:

        try:
            following_likebtn = driver.find_element(By.XPATH,
                                                    '//*[@aria-label="좋아요" and @height = "24"] //ancestor :: button')
            driver.execute_script("arguments[0].scrollIntoView({block : 'center'});", following_likebtn)
            following_likebtn.click()
            following_likenum += 1
            # tk.Label(newwin, text=f"성공한 좋아요 : {following_likenum}개 누름").grid(row=0, column=0, padx=50, pady=50)
            print(f'피드 좋아요 {following_likenum}개 누름')
            lbox.insert(END, f'피드 좋아요 {following_likenum}개 누름')
            lbox.update()
            lbox.see(END)
            time.sleep(round(random.randrange(10)))
        except:
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            driver.implicitly_wait(10)
    now = str(datetime.datetime.now())[0:-7]
    lbox.insert(END, f'[{now}] 피드좋아요 끝!!!!!!!!!!!!!!!')
  • 로그인 → 좋아요태그확인 → 좋아요 → 스크롤내리기 → 반복
  • following_likebtn : 좋아요 버튼 찾기
  • driver.execute_script("arguments[0].scrollIntoView({block : 'center'});", following_likebtn) : 좋아요 버튼이 화면 중앙에 보이도록 스크롤 이동
  • except :예외가 발생하면 스크롤을 맨아래까지 내리고 일정시간대기 후 다시 좋아요 작업 반복
  • now : 좋아요작업 끝낸시간 출력
win= Tk()
win.geometry("500x400")
win.title("오고곡")

login_id = Entry(win)
login_pw = Entry(win)
feed_entry = Entry(win)
hashtag_entry = Entry(win)
hashtaglike_entry = Entry(win)

login_id.grid(row=0,column=1)
login_pw.grid(row=1,column=1)
feed_entry.grid(row=2,column=1)
hashtag_entry.grid(row=3,column=1)
hashtaglike_entry.grid(row=4,column=1)

tk.Label(win, text = "Username : ").grid(row = 0, column = 0, padx = 10, pady = 10)
tk.Label(win, text = "Password : ").grid(row = 1, column = 0, padx = 10, pady = 10)
tk.Label(win, text = "피드 좋아요 수 : ").grid(row = 2, column = 0, padx = 10, pady = 10)
tk.Label(win, text = "해시태그 : ").grid(row = 3, column = 0, padx = 10, pady = 10)
tk.Label(win, text = "좋아요수 : ").grid(row = 4, column = 0, padx = 10, pady = 10)

btn1 = Button(win,text='좋아요❤',bg='pink',fg='black',command=feed).grid(row=2,column=2)
btn2 = Button(win,text='해시태그🙏🙏',bg='pink',fg='black',command=hashtag).grid(row=4,column=2)
btn3 = Button(win,text='좋아❤태그🙏',bg='pink',fg='black',command=final).grid(row=5,column=1)

label_title = Label(win, text='')
label_title.grid(row=10, column=3, sticky="w")
scroll = Scrollbar(win, orient='vertical')
lbox = Listbox(win, yscrollcommand=scroll.set, width=70)
scroll.config(command=lbox.yview)
lbox.grid(row=6, column=0, columnspan=5, sticky="s")

win.mainloop()
  • win: GUI프로그래밍을 위한 TK모듈 정의 
  • Entry : id,pw,좋아요등의 값을 입력받는 필드
  • btn : 버튼클릭 시 해당 함수 실행(feed,hashtag,final)
  • win.mainloop() : GUI창을 사용자가 직접 종료할때 까지 열어둠