똑같은 코드라도, 실행이 안될때가 있음
그건, 필요한 라이브러리 설치가 안됫기때문인데
이 라이브러리를 설치 햇는데도 실행이 안되는 경우가 있음
"파이썬 실행 환경 불일치" 문제입니다.
문제의 핵심 원인
터미널(CMD)에서 사용하는 파이썬과, 코드를 실행하는 프로그램(예: VS Code, Jupyter, PyCharm)이 사용하는 파이썬이 서로 다른 별개의 파이썬이기 때문입니다.
컴퓨터에는 여러 버전의 파이썬이 설치될 수 있습니다. (예: 시스템 기본 파이썬, 사용자가 따로 설치한 파이썬, Anaconda 파이썬, 가상환경의 파이썬 등)
현재 상황을 비유하자면 이렇습니다.
- 사용자: (터미널에서) "내 A 서랍(c:\python312\)에 webdriver-manager 책 좀 넣어줘."
- pip: "네, 이미 A 서랍에 그 책이 있습니다."
- 사용자: (코드 에디터에서) "자, 이제 코드를 실행해줘!"
- 코드 에디터: "알겠습니다. B 서랍에 있는 파이썬으로 실행할게요. 어? 그런데 B 서랍에는 webdriver-manager 책이 없네요. ModuleNotFoundError!"
즉, 터미널은 c:\python312라는 경로의 파이썬을 가리키고 있지만, 실제 코드를 실행하는 환경은 다른 곳에 설치된 파이썬을 사용하고 있는 것입니다.
해결 방법: 올바른 파이썬 환경에 라이브러리 설치하기
가장 확실한 해결책은 코드를 실행하는 바로 그 환경에 직접 라이브셔리를 설치하는 것입니다.
어떤 환경에서 코드를 실행하고 계신가요? 경우에 따라 해결 방법이 약간 다릅니다.
경우 1: Visual Studio Code (VS Code) 사용 시
VS Code는 현재 사용 중인 파이썬 환경(인터프리터)을 화면 하단에 표시해 줍니다.
- VS Code의 터미널을 사용하세요.
- VS Code 상단 메뉴에서 터미널(Terminal) -> 새 터미널(New Terminal)을 엽니다.
- VS Code 내장 터미널은 현재 선택된 파이썬 환경에 맞춰져 있을 확률이 높습니다.
- 그 터미널에 아래 명령어를 다시 입력하고 실행합니다.
- 파이썬 인터프리터를 직접 지정하여 설치
- 화면 오른쪽 아래(또는 왼쪽 아래)에 Python 3.x.x와 같이 생긴 부분을 클릭합니다. 그러면 VS Code가 인식하고 있는 모든 파이썬 설치 경로 목록이 나타납니다.
- 이 목록을 통해 현재 어떤 파이썬으로 코드를 실행하고 있는지 확인하고, 그 파이썬에 직접 모듈을 설치해야 합니다.
- 가장 확실한 방법은 아래와 같이 -m 플래그를 사용하는 것입니다.
(만약 python 명령어가 안 되면 python3로 시도해보세요)# 현재 VS Code가 사용하는 파이썬으로 pip를 실행하라는 뜻 python -m pip install webdriver-manager python -m pip install seleniumUse code with caution.Bash
경우 2: Jupyter Notebook (Anaconda 또는 직접 설치) 사용 시
Jupyter Notebook/Lab은 자체 커널(실행 환경)을 사용합니다.
- 코드 셀에서 직접 설치 명령을 실행하세요.
- 가장 확실하고 간단한 방법입니다. 노트북의 코드 셀에 아래 코드를 입력하고 실행(Shift+Enter)하세요. !는 '이것은 파이썬 코드가 아니라 터미널 명령어다'라는 뜻입니다.Generated python
- 설치가 끝나면, 상단 메뉴에서 커널(Kernel) -> 커널 다시 시작(Restart Kernel)을 눌러 변경 사항을 적용한 후, 원래 코드 셀을 다시 실행합니다.
경우 3: PyCharm 사용 시
PyCharm은 프로젝트별로 가상환경을 만드는 것이 기본 설정입니다.
- PyCharm 하단의 Terminal 탭을 엽니다.
- 이 터미널은 현재 프로젝트의 파이썬 환경(가상환경일 가능성이 높음)에 자동으로 연결되어 있습니다.
- 여기에 pip install webdriver-manager를 입력하면 정확한 위치에 설치됩니다.
지금 바로 시도해볼 것
- 코드를 실행하고 있는 바로 그 프로그램(VS Code, Jupyter 등)에서 제공하는 터미널이나 코드 셀을 여세요.
- 아래 명령어를 입력하여 설치를 다시 시도하세요.Generated bash
# (VS Code, PyCharm 터미널에서) pip install webdriver-manager
# (Jupyter Notebook 코드 셀에서) !pip install webdriver-manager
즉, 그냥 cmd에

이렇게 입력하면 안된다는 의미

이렇게 주피터 노트북의 셸안에 입력해야함
근데 이 프로그램 실행중에 다른 활동 해도 이 프로그램은 정상적으로 실행되는가
1. 영향을 주는 활동 (주의! 피해야 할 행동)
이 활동들은 자동화 스크립트의 실행을 방해하거나 오류를 발생시킬 수 있습니다.
- 자동화 중인 브라우저 창을 직접 조작하는 행위:
- Selenium이 제어하고 있는 크롬 창을 최소화하거나, 다른 창 뒤로 숨기거나, 창 크기를 조절하는 경우.
- 해당 창에서 마우스로 다른 곳을 클릭하거나, 키보드로 무언가를 입력하는 행위.
- 이런 행동은 절대 금물입니다. Selenium은 특정 요소의 좌표를 기준으로 클릭을 시도하는데, 창이 최소화되거나 다른 요소가 클릭을 가리면 ElementNotInteractableException (클릭할 수 없음) 같은 오류가 발생합니다.
- 마우스 커서를 가져가는 행위:
- 사용자님의 코드는 ActionChains를 사용해 마우스를 정교하게 움직입니다. 이때 사용자가 마우스를 직접 움직여 자동화 중인 브라우저 창 위에 올려두면, 스크립트의 마우스 이동을 방해하여 의도치 않은 요소 위로 마우스가 올라가거나 클릭에 실패할 수 있습니다.
- 시스템 리소스를 많이 사용하는 다른 프로그램을 실행하는 경우:
- 고화질 동영상 인코딩, 무거운 게임, 대용량 파일 복사 등 CPU나 메모리를 많이 사용하는 작업을 동시에 하면 컴퓨터가 전반적으로 느려집니다.
- 이로 인해 웹페이지 로딩이 늦어져서 Selenium이 요소를 찾기 전에 타임아웃(TimeoutException)이 발생할 수 있습니다.
2. 영향을 주지 않는 활동 (안전한 행동)
자동화 스크립트에 거의 영향을 주지 않으므로 자유롭게 하셔도 됩니다.
- 자동화 중인 브라우저 창을 건드리지 않고 다른 작업하기:
- 가장 좋은 방법은 Selenium이 띄운 창은 그냥 화면 한쪽에 그대로 두고, 다른 모니터나 다른 공간에서 다른 작업을 하는 것입니다.
- 다른 브라우저 창(Chrome, Edge 등)을 새로 열어서 웹 서핑하기.
- 메모장, 워드, 엑셀 등 문서 작업하기.
- 카카오톡 같은 메신저 사용하기.
- 음악 듣기.
안전하게 멀티태스킹하는 팁
- "Headless" 모드 사용 (궁극의 해결책):
- 나중에 더 안정적인 자동화를 원하신다면 "헤드리스 모드"를 사용해 보세요.
- 이 모드는 화면에 브라우저 창을 아예 띄우지 않고 백그라운드에서 모든 작업을 처리합니다.
- 사용자는 화면에 보이는 게 없으므로 실수로 건드릴 일이 전혀 없고, 컴퓨터 자원도 더 적게 사용합니다.
- 설정 방법은 간단합니다. ChromeOptions에 아래 한 줄만 추가하면 됩니다.
# ... chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--headless") # 이 줄 추가 chrome_options.add_argument("--window-size=1920,1080") # 헤드리스 모드에서는 창 크기를 지정해주는 것이 좋습니다. driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options) # ...Use code with caution.Python- 단점: 눈으로 직접 진행 상황을 볼 수 없어 디버깅이 조금 더 어렵습니다. 코드가 완전히 안정화된 후에 적용하는 것을 추천합니다.
- 가상 데스크톱 사용 (Windows 기능):
- Windows의 가상 데K스크톱 기능을 활용하는 것도 좋은 방법입니다.
- Ctrl + Win + D 키를 눌러 새로운 가상 데스크톱을 만듭니다.
- 그곳에서 자동화 스크립트를 실행하고, 원래 데스크톱(Ctrl + Win + ←/→ 로 전환)으로 돌아와 다른 작업을 하면 서로 방해하지 않습니다.
요약:
Selenium이 띄운 브라우저 창은 "신성불가침 영역"이라고 생각하시고, 그 창만 건드리지 않으면 다른 작업은 대부분 괜찮습니다.
가장 안전한 방법은 스크립트가 돌아가는 동안 다른 창에서 작업을 하거나, 나중에 headless 모드를 도입하는 것입니다.

주석처리된 break를 해제하면 무한 루프를 돌고
break가 있으면 한번만 실행되는 구조임
전체 코드는 다음과 같음
import time
import random
from selenium import webdriver
from seleniuhttp://m.webdriver.common.by import By
from seleniuhttp://m.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from seleniuhttp://m.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from seleniuhttp://m.webdriver.common.action_chains import ActionChains
# --- [추가] 마우스 위치를 추적하고 출력하는 헬퍼 함수 ---
def setup_mouse_position_tracker(driver):
"""
브라우저에 마우스 위치를 추적하는 JavaScript를 주입합니다.
페이지가 로드된 후 한 번만 실행하면 됩니다.
"""
js_mouse_tracker = """
window.mousePos = { x: -1, y: -1 };
document.addEventListener('mousemove', function(event) {
window.mousePos = { x: event.clientX, y: event.clientY };
});
"""
driver.execute_script(js_mouse_tracker)
# print("[좌표 추적기 설치 완료]")
def print_mouse_position(driver, message=""):
"""
현재 기록된 마우스의 좌표를 가져와 출력합니다.
"""
try:
pos = driver.execute_script("return window.mousePos;")
# print(f" ㄴ [마우스 좌표 확인] {message}: X={pos['x']}, Y={pos['y']}")
except Exception as e:
# print(f" ㄴ [마우스 좌표 확인 실패] {message}: {e}")
pass
# --- 함수 정의 ---
def human_like_mouse_move_to_element(driver, element):
"""
[좌표 출력 버전] 마우스 이동 전/후의 좌표를 출력하여 실제 이동 여부를 검증합니다.
"""
# 1. 목표 요소를 화면 중앙으로 스크롤
driver.execute_script("arguments[0].scrollIntoView({block: 'center', behavior: 'smooth'});", element)
# print("목표('좋아요' 버튼)를 화면 중앙으로 스크롤했습니다.")
time.sleep(random.uniform(0.8, 1.5))
# print_mouse_position(driver, "이동 시작 전")
# 2. 첫 번째 이동: 목표 요소 근처의 다른 곳으로 이동
actions_step1 = ActionChains(driver)
element_size = element.size
offset_x = random.randint(int(element_size['width'] * 0.7), int(element_size['width'] * 1.5)) * random.choice([-1, 1])
offset_y = random.randint(int(element_size['height'] * 0.7), int(element_size['height'] * 1.5)) * random.choice([-1, 1])
actions_step1.move_to_element(element).move_by_offset(offset_x, offset_y).perform()
# print(f"1단계: 목표 근처(오프셋: {offset_x}, {offset_y})로 마우스를 이동합니다.")
# print_mouse_position(driver, "1단계 이동 직후")
time.sleep(random.uniform(0.5, 1.0))
# 3. 두 번째 이동: 최종적으로 목표 요소 위로 정확히 이동
actions_step2 = ActionChains(driver)
actions_step2.move_to_element(element).perform()
# print("2단계: 목표물에 마우스를 정확히 위치시킵니다.")
# print_mouse_position(driver, "2단계 이동 직후 (최종 위치)")
time.sleep(random.uniform(0.3, 0.6))
# print("마우스 이동 완료! 이제 클릭 준비가 되었습니다.")
# --- 메인 코드 ---
BASE_URL = "https://kimchangmin02.tistory.com"
TARGET_URLS = [f"{BASE_URL}/{i}" for i in range(1, 55)]
WAIT_TIMEOUT = 10
# print("진짜 최종 완성 버전! 자동 '좋아요' 로봇을 시작합니다. (좌표 추적 기능 포함)")
# print(f"총 {len(TARGET_URLS)}개의 게시물을 대상으로 작업을 반복합니다.")
# print("프로그램을 종료하려면 이 창에서 Ctrl + C 를 누르세요.")
while True:
driver = None
try:
target_page = random.choice(TARGET_URLS)
# print("\n--- 새로운 시도를 시작합니다 ---")
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
wait = WebDriverWait(driver, WAIT_TIMEOUT)
driver.get(target_page)
# print(f"'{target_page}' 페이지로 이동했습니다.")
# [중요] 페이지가 로드된 후, 마우스 좌표 추적기를 설치합니다.
setup_mouse_position_tracker(driver)
scroll_time = random.uniform(1.5, 4.0)
# print(f"사람처럼 행동하기 위해 {scroll_time:.2f}초 동안 페이지를 스크롤합니다...")
driver.execute_script(f"window.scrollTo(0, document.body.scrollHeight * 0.3);")
time.sleep(scroll_time)
like_button_selector = "div[id^='reaction-'] button.btn_post"
# print(f"CSS 선택자: '{like_button_selector}' 를 사용하여 '좋아요' 버튼을 찾습니다...")
like_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, like_button_selector)))
# print("성공: '좋아요' 버튼을 찾았습니다.")
human_like_mouse_move_to_element(driver, like_button)
like_button.click()
# print("성공: '좋아요' 버튼을 확실하게 클릭했습니다.")
time.sleep(random.uniform(0.5, 1.0))
# print("클릭 완료! 마우스 커서를 다른 곳으로 치웁니다...")
actions = ActionChains(driver)
body_element = driver.find_element(By.TAG_NAME, 'body')
actions.move_to_element_with_offset(body_element, 5, 5).perform()
# print("마우스 커서를 안전한 위치로 이동했습니다.")
# print_mouse_position(driver, "마지막 커서 이동 후")
viewing_time = random.uniform(2, 5)
# print(f"작업 완료! {viewing_time:.2f}초 더 머문 뒤 브라우저를 닫습니다.")
time.sleep(viewing_time)
except Exception as e:
# print(f"실패: 작업 중 오류가 발생했습니다 - {e}")
import traceback
# traceback.print_exc() # 오류의 상세 내용을 출력합니다.
error_sleep_time = random.uniform(5, 10)
# print(f"오류 발생으로 인해 {error_sleep_time:.2f}초 대기합니다.")
time.sleep(error_sleep_time)
finally:
if driver:
# print("브라우저를 종료합니다.")
driver.quit()
#break
break_time = random.uniform(10, 25)
# print(f"\n다음 시도를 위해 {break_time:.2f}초간 충분히 휴식합니다...")
time.sleep(break_time)
'개발 > 자동화' 카테고리의 다른 글
| [코드] 티스토리 자동 좋아요+비로그인 댓글(#9) (11) | 2025.07.26 |
|---|---|
| 티스토리 자동화 댓글 봇 만들기(2) (#8) (8) | 2025.07.26 |
| 티스토리 자동화 댓글 봇 만들기(이론) (#6) (13) | 2025.07.25 |
| 티스토리 좋아요 자동화 #5(가상 마우스가 움직이는거였음) (9) | 2025.07.25 |
| 티스토리 좋아요 자동화 #4(마우스 랜덤으로 움직이기에서 막힘) (17) | 2025.07.25 |