@hoon_studio : 개인 계정이었다가 운동계정으로 사용하다가 다시 계정을 분리하면서 개인계정으로 돌아옴
@hoon_fitness : 점심운동 등 운동을 기록하는 공간
@hoon_studywithme : 새벽에 미라클 모닝해서 신문이나 책 등 자기계발 하는 공간
* 제 개인/운동/공부 피드를 보려면 맞팔해주셔도 괜찮습니다.
다음 포스팅으로 다시 자동화 인스타 좋아요봇 만든 소스를 공개하겠지만,
먼저 이 3개 계정에 대한 좋아요 exe 실행파일을 만들고
동시에 돌려보았다. 1개 계정은 1번만 실행시키는 한계, 시간적 한계를 이겨내고 싶어서였다.
그 결과, 3개중 테스트를 가장 많이 진행하였던 개인 계정이 아래와 같이 봇 중지가 되었다.
* 회원님의 계정이 일시적으로 잠겼습니다
그래서 계정을 풀고 다시 노트북으로 확인해보니 이런식으로 다른 2개 계정은 잘 운영중이었고,
본 계정의 화면만 하얗게 표현되고 CMD창에도 에러로그가 떨어져있었다.
40번째 피드까지 좋아요 작업이후에 element를 찾지 못해서 에러 로그가 떨어진 것으로 나온다.
39번째 피드 좋아요 작업 완료
작업 간 대기시간은 40초 입니다.
좋아요
40번째 피드 좋아요 작업 완료
작업 간 대기시간은 32초 입니다.
Traceback (most recent call last):
File "likebot.py", line 141, in <module>
File "likebot.py", line 103, in bot
File "selenium\webdriver\remote\webdriver.py", line 564, in find_element_by_class_name
File "selenium\webdriver\remote\webdriver.py", line 976, in find_element
File "selenium\webdriver\remote\webdriver.py", line 321, in execute
File "selenium\webdriver\remote\errorhandler.py", line 242, in check_response
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".QBdPU.rrUvL"}
(Session info: chrome=96.0.4664.93)
[19924] Failed to execute script 'likebot' due to unhandled exception!
Instagram에 연결할 수 없습니다. 인터넷에 연결되어 있는지 확인한 후 다시 시도해보세요.
=> 인터넷이 되는 상황이었음. 그래서 봇 테스트 때문에 잦은 로그인으로 막혔나 싶어서 몇번을 재시도해도 동일하더니 시간이 1~2분 정도 더 지나니 다시 잘되었다. 혹시나 메일로 이상 로그인 시도 탐지 메일이 왔을줄 알았는데 별도로 오지는 않았다. (예전에 테스트 하는 동안 이상감지 메일이 5개 정도왔던 기억때문에 확인해봄)
Traceback (most recent call last):
File "D:\05.Lab\02.python\20211214_insta_like_bot\likebot.py", line 142, in <module>
bot()
File "D:\05.Lab\02.python\20211214_insta_like_bot\likebot.py", line 102, in bot
like_btn = driver.find_element_by_xpath('/html/body/div[6]/div[2]/div/article/div/div[3]/div/div/section[1]/span[1]')
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 394, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div[6]/div[2]/div/article/div/div[3]/div/div/section[1]/span[1]"}
(Session info: chrome=96.0.4664.93)
기존에 인스타 좋아요 봇을 어느정도 만들었는데, 노트북을 SSD로 교체하면서 기존 파일 백업이 제대로 안되었나보다.
그래서 HDD를 다시 꽂아서 복사하기 보다는 기존 내 포스팅을 참고해서 다시 코딩을 해보려고 한다.
어차피 파이썬도 안쓰는 동안 많이 잊어서 공부하는 겸사겸사 하려고 한다. (속으로는 백업의 중요성을 다시 깨달았다)
pycharm에서 pip도 실행할 수 있도록 pip를 설치하였다.
노란색 코멘트는 pip 21.3.1 버전 사용가능하다는 레코멘드.
chromedriver는 직접 더블클릭으로 설치가 아닌 selenium에서 바라보는 경로를 지정해주어야 한다.
그렇지 않으면 아래와 같이 에러가 나온다.
D:\05.Lab\02.python\20211214_insta_like_bot\main.py:24: DeprecationWarning: executable_path has been deprecated, please pass in a Service object
driver = webdriver.Chrome(driver_path, options=options)
Traceback (most recent call last):
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\common\service.py", line 71, in start
self.process = subprocess.Popen(cmd, env=self.env,
File "C:\Users\move_\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 947, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "C:\Users\move_\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1416, in _execute_child
hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] 지정된 파일을 찾을 수 없습니다
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\05.Lab\02.python\20211214_insta_like_bot\main.py", line 81, in <module>
bot()
File "D:\05.Lab\02.python\20211214_insta_like_bot\main.py", line 24, in bot
driver = webdriver.Chrome(driver_path, options=options)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 70, in __init__
super(WebDriver, self).__init__(DesiredCapabilities.CHROME['browserName'], "goog",
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\chromium\webdriver.py", line 90, in __init__
self.service.start()
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\common\service.py", line 81, in start
raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: 'chromedriver.exe' executable needs to be in PATH. Please see https://chromedriver.chromium.org/home
Process finished with exit code 1
나의 경우에는 main.py 파일이 있는 동일 경로에 chromedriver 파일을 복사해두었다.
그랬더니 예전에는 보지 못하였던 새로운 에러가 떨어졌다.
D:\05.Lab\02.python\20211214_insta_like_bot\main.py:24: DeprecationWarning: executable_path has been deprecated, please pass in a Service object
driver = webdriver.Chrome(driver_path, options=options)
로그인중....
D:\05.Lab\02.python\20211214_insta_like_bot\main.py:35: DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instead
id_input = driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[1]/div/label')
D:\05.Lab\02.python\20211214_insta_like_bot\main.py:40: DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instead
pw_input = driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[2]/div/label')
D:\05.Lab\02.python\20211214_insta_like_bot\main.py:45: DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instead
login_btn = driver.find_element_by_xpath('//*[@id="loginForm"]/div/div[3]/button')
D:\05.Lab\02.python\20211214_insta_like_bot\main.py:56: DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() instead
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]')
Traceback (most recent call last):
File "D:\05.Lab\02.python\20211214_insta_like_bot\main.py", line 81, in <module>
bot()
File "D:\05.Lab\02.python\20211214_insta_like_bot\main.py", line 56, in bot
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]')
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 520, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 1244, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 422, in execute
response = self.command_executor.execute(driver_command, params)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 421, in execute
return self._request(command_info[0], url, body=data)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 443, in _request
resp = self._conn.request(method, url, body=body, headers=headers)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\urllib3\request.py", line 78, in request
return self.request_encode_body(
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\urllib3\request.py", line 170, in request_encode_body
return self.urlopen(method, url, **extra_kw)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\urllib3\poolmanager.py", line 375, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\urllib3\connectionpool.py", line 699, in urlopen
httplib_response = self._make_request(
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\urllib3\connectionpool.py", line 445, in _make_request
six.raise_from(e, None)
File "<string>", line 3, in raise_from
File "D:\05.Lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\urllib3\connectionpool.py", line 440, in _make_request
httplib_response = conn.getresponse()
File "C:\Users\move_\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1347, in getresponse
response.begin()
File "C:\Users\move_\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 307, in begin
version, status, reason = self._read_status()
File "C:\Users\move_\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 268, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "C:\Users\move_\AppData\Local\Programs\Python\Python39\lib\socket.py", line 704, in readinto
return self._sock.recv_into(b)
KeyboardInterrupt
Process finished with exit code -1073741510 (0xC000013A: interrupted by Ctrl+C)
아래처럼 취소선이 왜 생겼는지 보니 selenium 버전이 4버전이 되면서 라이브러리가 변경되서 warning도 뜨고 한다고 함. 그래서 기존대로 3버전으로 낮추는 작업을 진행함.
PS D:\05.Lab\02.python\20211214_insta_like_bot> pip uninstall selenium
Found existing installation: selenium 4.1.0
Uninstalling selenium-4.1.0:
Would remove:
d:\05.lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium-4.1.0.dist-info\*
d:\05.lab\02.python\20211214_insta_like_bot\venv\lib\site-packages\selenium\*
pip를 3버젼대로 설치하고나니 취소선이 다시 없어짐
PS D:\05.Lab\02.python\20211214_insta_like_bot> pip3 install selenium=3.141
ERROR: Invalid requirement: 'selenium=3.141'
Hint: = is not a valid operator. Did you mean == ?
WARNING: You are using pip version 21.1.2; however, version 21.3.1 is available.
Collecting selenium==3.141
Downloading selenium-3.141.0-py2.py3-none-any.whl (904 kB)
|████████████████████████████████| 904 kB 6.4 MB/s
Requirement already satisfied: urllib3 in d:\05.lab\02.python\20211214_insta_like_bot\venv\lib\site-packages (from
selenium==3.141) (1.26.7)
Installing collected packages: selenium
Successfully installed selenium-3.141.0
WARNING: You are using pip version 21.1.2; however, version 21.3.1 is available.
You should consider upgrading via the 'D:\05.Lab\02.python\20211214_insta_like_bot\venv\Scripts\python.exe -m pip i
nstall --upgrade pip' command.
숫자가 커질수록 연산과정이 많아져서 '이거 루프 도는 건가?'라고 생각할때 즈음 결과값이 나오는 것을 보았다.
그렇다면 어떻게 개선해야하는 것인가?
- 알고리즘을 생각하고 개선 포인트를 찾자
- for문이 3번 들어가기 때문에 for문 번수 * for문 번수 * for문 번수 이기 때문에 for문을 1개만 줄여도 '마지막 for문 번수'만큼을 안 곱해도 된다.
[피타고라스 삼조 코딩 - 비효율적]
for a in range(1, 400):
a2 = a * a
for b in range(1, 400):
b2 = b * b
for c in range(1, 400):
c2 = c * c
if a2 + b2 == c2:
if a + b+ c == 400:
#print(a, b, c)
print(a*b*c)
[피타고라스 삼조 코딩 - 효율적으로 개선]
- for문을 1개 없애서 결과값 속도가 훨씬 빨라졌다.
'c = 400 - a - b'와 같이 표현할 수 있다는 것을 배웠다.
for a in range(1, 400):
for b in range(1, 400):
c = 400 - a - b
if a*a + b*b == c*c:
if a + b + c == 400 and a < b < c:
print(a, b, c)
print(a*b*c)
** 이 문제는 a + b + c 가 400이면서 피타고라스 삼조를 만족시키는 샘플 문제에 대한 코딩이다.
그에 대한 코드이다. (아이디, 패스워드를 하드코딩하는 이유는 exe 파일로 만들어서 바로 스케쥴링 걸수있도록)
[개선 포인트]
- 친절한 안내 : 총 갯수, 선택 해시태그, 몇초후 시작, 종료되었습니다
- 컨텐츠 작업 : 랜덤
- 해시태그 선택 : 랜덤
- 좋아요작업 다음피드 : 랜덤으로 이동 (random.randint 모듈 사용)
=> 실제 인스타에서 어떻게 작동하는지 모름. 테스트해보려고 하였으나, 이미 경고받아서인지 실행 2번만에 경고팝업
- 해당 코드를 7/20부터 돌려서 사용예정 (스케쥴링 적용 - 하루 3번) => 06시, 12시, 18시 (어차피 시작시간도 랜덤딜레이여서 정각으로 걸어도 됨)
[추가 개선포인트]
- 어느정도 돌리면 해시태그를 바꾸어서 또 누르고 (랜덤하게)
=> 정말 불규칙하게 가는 것인데, 1시간 넘게 이전 코딩 개선하느라 머리가 잘 안돌아감
[인사이트]
- 알고리즘도 결국 정형화되고, 경험을 쌓아서 이런 패턴이면 봇이겠구나 라는 것을 깨닫는 구조이다.
그렇기 때문에 나조차 패턴이 전혀 예측이 안되는 코딩을 하면되지않을까.
=> 패턴 = 랜덤 * 랜덤 * 랜덤 * .....
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import inspect, os, platform, time, random
def bot():
#좋아요 갯수 랜덤 정의
rand_cnt = random.randrange(182, 297)
print("이번 좋아요 작업의 총 피드 갯수는 {}개입니다".format(rand_cnt))
rand_tag = ['운동하는직장인','운동하는남자','운동하는여자','운동인증','운동일기','운동일지','눈바디','피트니스','직장인스타그램','운동스타그램','홈트','홈트레이닝']
#필요한 변수 정의
insta_id = '블라블라'
insta_pw = '블라블라'
insta_tag = random.choice(rand_tag) # 해시태그 하나 선택
print("작업할 해시태그는 '{}'입니다.".format(insta_tag))
insta_cnt = rand_cnt
insta_sort = 1
#크롬드라이버 로딩
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)
### 인스타그램 자동 좋아요 작업 ###
#
# 0. 좋아죠 시작작업 랜덤 적용
random_wait_time = random.randrange(3, 5)
print("좋아요 작업은 {}초 후에 시작됩니다".format(random_wait_time))
# 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)
# add. 로그인정보 저장 > '나중에 하기' 버튼 클릭
later_btn = driver.find_element_by_xpath('//*[@id="react-root"]/section/main/div/div/div/div/button')
later_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)
print("좋아요 작업 시작합니다")
# 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초 이상을 설정해주세요.
rand_time = random.randrange(24,58)
time.sleep(rand_time)
print(rand_time) # 랜덤 시간 주기 24~58s
# 7. 좋아요 작업 - 다음 피드로 이동
if idx < insta_cnt:
try:
i = 0
while i != 2:
i = random.randint(1,3)
next_feed = driver.find_element_by_link_text('다음')
next_feed.click()
time.sleep(1) # '다음' 클릭 딜레이 간격
except NoSuchElementException as n:
print('피드 개수 부족으로 작업이 종료됩니다.')
break
print('계획된 {} 좋아요 작업이 모두 완료되었습니다'.format(insta_cnt))
driver.quit()
bot()