파이썬 인스타그램 자동화 - 자동 댓글 작성하기
이전 포스팅에서 인스타그램 자동 댓글 작성 기능을 구현했습니다. 그런데 내 프로그램이 이미 댓글 작성한 피드에 중복으로 댓글을 작성한다면? 게시자 입장에서 참 이상한 상황이라고 생각을 할 수도 있고, 프로그램 사용을 의심할수도 있겠죠 ㅠㅠ
이런 문제를 방지하기 위해 댓글 작성전 이미 댓글을 작성했는지 확인하는 기능을 추가하겠습니다.
이전 강의 - 인스타그램 자동 좋아요, 자동 댓글
지난번에 작성한 소스코드에 이어서 작성했으니 아래의 링크에서 지난 강의를 참고해주세요.
작업환경
윈도우10, VS Code, Python3, Chrome88
프로그램 구동 화면
댓글 작성 확인 기능 추가
#9. 이미 댓글을 작성했는지 확인
div = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div[3]')
comm_area = div.find_element_by_tag_name('div')
ul = div.find_element_by_tag_name('ul')
ul1 = ul.find_elements_by_class_name('Mr508') #9-1. 현재보여지는 댓글개수
if len(ul1) >= 12:
while True:
#9-2. 보여지는 댓글개수가 11개가 넘으면 끝까지 스크롤
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", ul)
time.sleep(random.randint(500, 1000)/1000)
before_comm_cnt = len(ul1)#9-3. 더보기 버튼 클릭 하기 전 보여지는 댓글개수
time.sleep(2)
#댓글 더 보기 버튼
add_btn = ul.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div[3]/div[1]/ul/li')
add_btn.click()
time.sleep(2)
div = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div[3]')
comm_area = div.find_element_by_tag_name('div')
ul = div.find_element_by_tag_name('ul')
ul1 = ul.find_elements_by_class_name('Mr508') # 9-4. 더보기 버튼 클릭 한 후 보여지는 댓글개수
after_comm_cnt = len(ul1)#현재보여지는 댓글개수
#9-5. 이전 댓글과 현재 댓글수가 같으면 정지, 같지 않으면 이전 댓글수에 입력
if before_comm_cnt == after_comm_cnt:
break
else:
before_comm_cnt += after_comm_cnt
break
# 9-6. 댓글 목록에 내 아이디가 있는지 확인
user = ul.find_element_by_link_text(insta_id)
print('이미 댓글을 작성한 피드입니다.')
9, 9-1, 9-2. 이미 댓글을 작성했는지 확인하려면 댓글 전체 목록을 확인해야겠죠? 하지만 인스타그램의 댓글은 11개가 넘으면 더보기 버튼을 클릭해야 나머지 댓글도 볼 수가 있습니다. 처음에 보여지는 댓글 개수를 확인한 후 (9-1) 11개 이상이면 댓글 제일 아래로 스크롤 한 후 + 버튼을 클릭해야 합니다.
9-3, 9-4. + 버튼 클릭 하기전! before_comm_cnt 에 현재 보여지는 댓글 개수를 넣어준뒤에 + 버튼을 클릭합니다. 그리고 클릭하고 난 뒤에 댓글 개수를 after_comm_cnt 에 넣어줍니다.
9-5. 이전 댓글수(before_comm_cnt)와 현재 댓글수(after_comm_cnt)를 비교하여 작업을 멈출지 계속 이어갈지 정해야합니다. 더 보기 버튼을 클릭해도 이전 댓글수와 현재댓글 수가 같으면 더 이상 스크롤 + 더보기 클릭 작업을 하지 않아도 되니 break를 통해 반복문을 빠져나와 주면되겠죠? 반대로 같지 않다면 before_comm_cnt 에 현재 댓글수를 넣어주고 스크롤 + 더보기 작업을 계속 반복해줍니다.
9-6. 댓글이 모두 보이게 되면 댓글 목록에서 처음 선언한 변수에 있는 나의 인스타그램 아이디로 된 링크가 있는지 확인해줍니다. 이 부분에서 NoSuchElementException 에러가 발생하지 않는다면 이미 작성된 댓글이 있다는 뜻이겠죠!
댓글 작성 확인 후 댓글 작성하기
NoSuchElementException 에러가 발생하지 않았을때 이미 작성한 댓글이 있는거라면, 만약 이미 작성한 댓글이 없을때는 에러가 난다는 뜻일까요??
맞습니다 ㅎㅎ. 그래서 이 부분을 try ~ except 처리하여 에러가 발생할 경우 댓글을 작성하도록 구현하면 됩니다. 물론 지난 강의에서 작성했던 소스와는 달라지겠죠? 아래의 전체 소스코드에서 확인해주세요 :)
테스트 방법
댓글 중복 확인 기능을 테스트하기에 딱 좋은 방법은 '인기피드순'으로 작업 한 뒤에 다시 '인기피드순'으로 작업하는겁니다. 최신피드순으로 작업을 하게되면 피드가 자주 바뀌어 확인하기 힘드니 해당 기능을 확인하고 싶은분들은 '인기피드순'으로 테스트해보세요.
혹시나해서! 주의사항
인스타그램은 정해진 시간동안 볼 수 있는 데이터(피드, 댓글, 팔로워 등)양이 정해져 있습니다. 이 정해진 양을 넘기게 되면 해당 데이터는 일정시간동안 보여지지 않고 무한로딩이 되어버립니다. 그렇기때문에 댓글 목록을 확인할때 댓글 로딩도 기다릴겸 time.sleep으로 약간의 대기시간을 설정해두었습니다.
혹시나 대기시간을 제거하실 분들은 참고하시길 바랍니다.
전체 소스코드
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import inspect, os, platform, time, random
def bot():
#필요한 변수 정의
insta_id = '인스타그램아이디'
insta_pw = '인스타그램패스워드'
insta_tag = '개냥이(#제외)'
insta_cnt = int(input('작업횟수(숫자만) : '))
insta_sort = '0' # '0' = 인기게시물에 작업, '1' = 최근게시물에 작업
## 댓글
insta_comm = ['넘 귀여워요!', '꺄 귀여워요! 잘 보고갑니다!', '귀염귀염 :)']
#크롬드라이버 로딩
options = webdriver.ChromeOptions()
options.add_argument('--disable-gpu')
options.add_argument('user-agent=Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36')
current_folder = os.path.realpath(
os.path.abspath(os.path.split(inspect.getfile(inspect.currentframe()))[0]))
if platform.system() == 'Windows':
driver_path = os.path.join(current_folder, 'chromedriver.exe')
else:
driver_path = os.path.join(current_folder, 'chromedriver')
driver = webdriver.Chrome(driver_path, options=options)
driver.implicitly_wait(10)
### 인스타그램 자동 좋아요 작업 ###
# 1. 인스타그램 로그인 페이지로 이동
driver.get('https://www.instagram.com/?hl=ko')
print('로그인중....')
time.sleep(3)
# 2. 아이디 입력창을 찾아서 위에서 입력받은 아이디(insta_id)값 입력
id_input = driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[1]/div/label')
id_input.click() #입력창 클릭
id_input.send_keys(insta_id) #아이디 입력
# 2-1. 패스워드 입력창을 찾아서 위에서 입력받은 패스워드(insta_pw)값 입력
pw_input = driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[2]/div/label')
pw_input.click()
pw_input.send_keys(insta_pw)
# 3. 로그인 버튼 클릭
login_btn = driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[3]/button')
login_btn.click()
# 잠시 대기
time.sleep(3)
# 4. 작업할 해시태그 검색 결과 페이지로 이동
driver.get('https://www.instagram.com/explore/tags/{}/'.format(insta_tag))
time.sleep(2)
# 5. 인기게시물 혹은 최근게시물 첫번째 피드 선택
if insta_sort == '0':
#인기게시물 첫번째 피트 선택
hot_first_feed = driver.find_element_by_xpath('//*[@id="react-root"]/section/main/article/div[1]/div/div/div[1]/div[1]/a/div/div[2]')
hot_first_feed.click()
else:
#최근게시물 첫번째 피드 선택
new_first_feed = driver.find_element_by_xpath('//*[@id="react-root"]/section/main/article/div[2]/div/div[1]/div[1]/a/div[1]/div[2]')
new_first_feed.click()
time.sleep(1)
# 6. 좋아요 작업 - 입력한 횟수만큼 반복 작업
for idx in range(insta_cnt):
div = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div')
div = div.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div[3]')
like_btn = div.find_element_by_tag_name('button') #좋아요 버튼
btn_svg = like_btn.find_element_by_tag_name('svg')
svg_txt = btn_svg.get_attribute('aria-label')
if svg_txt != '좋아요':
print('이미 좋아요 작업한 피드')
else:
like_btn.click() #좋아요 클릭
print('{}번째 피드 좋아요 작업 완료'.format(idx + 1))
# 너무 빠르게 작업을 할 경우 많은 양의 작업을 하게 되어 인스타그램측에서 계정 정지나 경고를 할 수 있으니
# 작업과 다음 작업 사이의 속도를 조절하기 위해 20초 이상을 설정해주세요.
time.sleep(5)
# 7. 좋아요 작업 - 다음 피드로 이동 -> 댓글 작성 아래로...
#9. 이미 댓글을 작성했는지 확인
div = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div[3]')
comm_area = div.find_element_by_tag_name('div')
ul = div.find_element_by_tag_name('ul')
ul1 = ul.find_elements_by_class_name('Mr508') #9-1. 현재보여지는 댓글개수
try:
if len(ul1) >= 12:
while True:
#9-2. 보여지는 댓글개수가 11개가 넘으면 끝까지 스크롤
driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight", ul)
time.sleep(random.randint(500, 1000)/1000)
try:
before_comm_cnt = len(ul1)#9-3. 더보기 버튼 클릭 하기 전 보여지는 댓글개수
time.sleep(2)
#댓글 더 보기 버튼
add_btn = ul.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div[3]/div[1]/ul/li')
add_btn.click()
time.sleep(2)
div = driver.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div[3]')
comm_area = div.find_element_by_tag_name('div')
ul = div.find_element_by_tag_name('ul')
ul1 = ul.find_elements_by_class_name('Mr508') # 9-4. 더보기 버튼 클릭 한 후 보여지는 댓글개수
after_comm_cnt = len(ul1)#현재보여지는 댓글개수
#9-5. 이전 댓글과 현재 댓글수가 같으면 정지, 같지 않으면 이전 댓글수에 입력
if before_comm_cnt == after_comm_cnt:
break
else:
before_comm_cnt += after_comm_cnt
except NoSuchElementException as ne:
break
# 9-6. 댓글 목록에 내 아이디가 있는지 확인
user = ul.find_element_by_link_text(insta_id)
print('이미 댓글을 작성한 피드입니다.')
except NoSuchElementException as n:
#8. 댓글 작성 영역 찾기
div = driver.find_element_by_xpath('/html/body/div[5]/div[2]')
div1 = div.find_element_by_xpath('/html/body/div[5]/div[2]/div')
article = div1.find_element_by_xpath('/html/body/div[5]/div[2]/div/article')
div2 = article.find_element_by_xpath('/html/body/div[5]/div[2]/div/article/div[3]')
section = div2.find_element_by_css_selector('div.eo2As > section.sH9wk._JgwE')
ta = section.find_element_by_tag_name('textarea')
time.sleep(2)
#8-1. 댓글 작성 영역으로 이동해 댓글창 클릭
ac = ActionChains(driver)
ac.move_to_element(ta)
ac.click()
ac.pause(2)
#8-2. 여러개의 댓글 중 랜덤으로 선택
choice_comm = (random.choice(insta_comm))
comm = choice_comm.split('\n')
#8-3. 댓글 작성
for i, c in enumerate(comm):
c = c.replace("\n", "")
ac.send_keys(c)
i += 1
#8.4. 댓글이 여러줄일 경우 Shift + Enter로 다음 줄 이동
if i < len(comm):
ac.key_down(Keys.SHIFT).send_keys(Keys.ENTER).key_up(Keys.SHIFT)
ac.pause(2)
ac.send_keys(Keys.ENTER)
#8-5. 등록한 ac 실행
ac.perform()
print('댓글 작성 성공 - {}'.format(choice_comm))
time.sleep(5)
# 7. 좋아요 + 댓글 작업 완료 후 다음 피드 이동
if idx < insta_cnt:
try:
next_feed = driver.find_element_by_link_text('다음')
next_feed.click()
except NoSuchElementException as n:
print('피드 개수 부족으로 작업이 종료됩니다.')
break
print('모든 작업 완료')
driver.quit()
bot()
다음 포스팅에서 구현할 기능
- 인스타그램 자동 팔로우
공감과 댓글은 작성자에게 많은 힘이됩니다. 감사합니다😄
'인스타그램 자동화' 카테고리의 다른 글
인스타그램 무료 자동 좋아요 댓글 팔로우 프로그램 (2021/02/09 업데이트) (15) | 2022.03.01 |
---|---|
[파이썬(Python)] 인스타그램 자동 프로그램 만들기 - 자동 팔로우 (4) | 2021.03.17 |
[파이썬(Python)] 인스타그램 자동 프로그램 만들기 - 자동 댓글 (1) (2) | 2021.02.27 |
인스타그램 자동 좋아요 프로그램 만들기 - 파이썬(python), 셀레니움(selenium) - 기능 강화 및 예외 처리 (5) | 2021.02.02 |
인스타그램 자동 좋아요 프로그램 만들기 - 파이썬(python), 셀레니움(selenium) - 로그인, 원하는 횟수만큼 좋아요 작업 (8) | 2021.02.02 |
댓글