IT·개발

Python Selenium 4 마이그레이션: find_element_by_* 제거 및 변경점 해설

5월 16, 2026 3 min read

2020년 4월, 유튜브 강의 하나를 보다가 “이거 직접 해봐야겠다” 싶어서 Python + Selenium으로 네이버 이미지를 긁어오는 코드를 짰습니다. 당시 올렸던 포스팅은 짧은 인사말 네 줄, 코드 한 덩어리, 유튜브 출처 링크 하나가 전부였습니다. 그리고 “크롤링을 할때는 항상 주의해주시구요”라는 한 줄을 남기고 끝냈습니다.

6년이 지나 그 코드를 다시 꺼내봤습니다. 든 첫 생각은 “지금도 돌아갈까?”였습니다. 이 글은 원본 코드를 수정 없이 보존하면서, Selenium 3→4 마이그레이션에서 달라진 것들 — find_element_by_* 메서드 제거, ChromeDriver 경로 방식 변화, Selenium 4.6.0에 추가된 Selenium Manager — 을 2020년 네이버 이미지 크롤링 코드와 함께 정리한 회고입니다. 2020년의 팩트는 팩트대로, 2026년 시점의 분석은 분석으로 섹션을 나눠 구분했습니다.


1. 그때 그 코드 — 동기와 맥락

[2020년 팩트 구간]

학습 동기는 단순했습니다. “어느 사이트든 HTML 구조만 잘 분석하셔도 크롤링은 충분히 가능합니다”라는 말을 손으로 직접 확인해보고 싶었습니다. 참고한 건 유튜브 강의 한 편이었고, 출처는 당시 시청한 영상 링크(https://www.youtube.com/watch?v=HJN28B7OSzw)입니다. 영상 제목이나 작성자는 지금 별도로 확인하지 않았으므로 링크만 그대로 남깁니다.


2. 원본 코드 (2020년 당시 그대로)

[2020년 팩트 구간]

아래는 2020년 당시 그대로의 코드입니다. 현 시점에서는 §3·§4의 변경점을 반영해야 동작합니다.

코드의 핵심 흐름을 순서대로 짚으면:

  • webdriver.Chrome('./chromedriver')로 Chrome 브라우저를 기동하고 implicitly_wait(30) 설정
  • 네이버 이미지 검색 URL에 키워드를 붙여 접속
  • body 요소에 Keys.PAGE_DOWN을 3회 입력해 lazy load(스크롤 전까지 화면 밖 이미지가 아직 로드되지 않는 방식) 이미지를 화면에 불러냄 — 매 스크롤마다 1~3초 랜덤 슬립
  • img._img CSS 셀렉터로 이미지 태그를 수집하고, src'http'가 포함된 것만 결과에 담음
  • images/{keyword}/ 폴더를 생성한 뒤 urlretrieve로 하나씩 저장

코드에서 tqdm 라이브러리를 사용합니다. 루프 진행률을 터미널에 실시간으로 표시해주는 라이브러리로, 기본 Python에 포함되어 있지 않으므로 사전에 별도 설치가 필요합니다(pip install tqdm).

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time, random, os
from urllib.request import urlretrieve
from tqdm import tqdm

def get_images(keyword) :
    # 1~3 초 사이의 랜덤난수
    randomsl = random.uniform(1,3)

    print('Loading')
    # 스크롤 다운을 해야 되서 chromedriver 사용
    driver = webdriver.Chrome('./chromedriver')
    driver.implicitly_wait(30)
    url = 'https://search.naver.com/search.naver?where=image&sm=tab_jum&query={}'.format(keyword)
    driver.get(url)

    # 스크롤 다운을 하기 위한 select
    body = driver.find_element_by_css_selector('body')
    for i in range(3) :
        body.send_keys(Keys.PAGE_DOWN)
        time.sleep(randomsl)    # 1~3초 사이 난수 적용

    # 이미지 tag select
    imgs = driver.find_elements_by_css_selector('img._img')
    result=[]
    for img in tqdm(imgs) :
        if 'http' in img.get_attribute('src') :
            result.append(img.get_attribute('src'))

    driver.close()
    print('Search End')

    # images 폴더 아래에 크롤링 하는 사람의 폴더를 생성
    path = 'images/'
    if not os.path.isdir(path + './{}'.format(keyword))  :
        os.mkdir(path + './{}'.format(keyword) + '/')
        print('{}'.format(keyword) + 'make folders')
    else :
        print('{}'.format(keyword) + 'be folders')

    # 이미지 다운로드
    for index, link in tqdm(enumerate(result)) :
        start = link.rfind('.')
        end = link.rfind('&')
        filetype = link[start : end]
        urlretrieve(link, path + './{}/{}{}'.format(keyword, index, filetype))
        time.sleep(randomsl)    # 1~3초 사이 난수 적용

    print('DownLoad End')

if __name__ == "__main__":
    keyword = input('who Search: ')
    get_images(keyword)

3. Selenium 4 핵심 변경점 — find_element_by_* 제거와 그 이후

[2026년 분석 구간 — Selenium 공식 마이그레이션 가이드(selenium.dev) 기준]

이 코드를 지금 그대로 실행하면 첫 번째 find_element_by_css_selector 호출부터 막힐 가능성이 큽니다. Selenium 4가 2021년 10월 정식 릴리즈되면서 기존 API 일부가 제거됐기 때문입니다.

원본 코드는 Selenium 3.x를 기반으로 작성된 것으로 추정됩니다. 추정이며, 작성 당시 정확한 버전은 별도로 기록하지 않아 단정할 수 없습니다.

find_element_by_* 메서드 제거

원본에서 쓰인 find_element_by_css_selector('body')find_elements_by_css_selector('img._img') — 이 두 줄이 직접 영향을 받습니다. Selenium 공식 마이그레이션 가이드에 따르면, By 클래스를 별도로 임포트하고 find_element(By.CSS_SELECTOR, ...) 형태로 전환하는 방식이 권장됩니다.

By 클래스의 임포트 경로는 아래와 같습니다:

from selenium.webdriver.common.by import By

코드 두 줄을 수정해야 하지만, Selenium 버전을 올리기 전에 이 부분을 그냥 넘기면 AttributeError가 발생하면서 실행이 멈출 가능성이 높습니다.

ChromeDriver 경로 지정 방식 변화

webdriver.Chrome('./chromedriver')는 ChromeDriver 실행 파일을 직접 같은 폴더에 내려받아 경로를 맞춰줘야 했습니다. Chrome 버전이 업데이트될 때마다 드라이버도 손으로 다시 받아야 했던 번거로움이 있었죠. Selenium 4 이후 공식 마이그레이션 가이드에서는 Service 객체를 별도로 생성해 드라이버에 전달하는 구조를 안내하고 있습니다.

Selenium Manager — Selenium 4.6.0부터 추가

Selenium 4.6.0(2022년 9월)부터 추가된 Selenium Manager는 설치된 브라우저 버전을 감지해 호환되는 ChromeDriver를 자동으로 내려받는 방식을 지원합니다. 예전처럼 ./chromedriver 파일을 직접 관리하지 않아도 되는 경우가 생겼습니다. Selenium 4.0~4.5에는 이 기능이 포함되지 않으므로, 버전을 혼동하지 않도록 주의가 필요합니다. 공식 문서 기준 설명이며, 실제 동작은 환경에 따라 다를 수 있습니다.

이 글에서는 Selenium 4 스타일로 재작성한 신규 코드를 추가하지 않겠습니다. 테스트하지 않은 예제를 올리는 것보다, 변화 방향을 파악한 뒤 공식 마이그레이션 가이드를 직접 보고 적용하는 편이 낫다고 생각합니다.

참고 URL:

  • Selenium 공식 마이그레이션 가이드: <https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/>
  • Selenium Manager 공식 문서: <https://www.selenium.dev/documentation/selenium_manager/>

4. 셀렉터는 살아있을까 — 사이트 구조 변화

[2026년 분석 구간]

img._img는 2020년 당시 네이버 이미지 검색 결과 썸네일에 붙어있던 CSS 클래스명이었습니다. 그게 지금도 그대로인지는 직접 확인하지 않았습니다.

네이버 검색 결과 페이지는 그동안 여러 차례 개편됐다는 게 일반적인 인식입니다. Selenium 호환성 문제를 해결하더라도, 셀렉터가 달라졌다면 이미지를 한 장도 가져오지 못하는 상황이 생길 수 있습니다.

셀렉터를 다시 조사하는 방법은 단순합니다. 브라우저에서 네이버 이미지 검색 결과 페이지를 열고, 원하는 썸네일 이미지에서 오른쪽 클릭 → “검사(Inspect)”를 선택하면 해당 태그의 클래스명을 바로 확인할 수 있습니다. 현재 어떤 클래스명을 쓰는지는 직접 확인해야 하며, 이 글에서는 임의로 추가하지 않겠습니다.


5. 공식 API와 크롤링 윤리

[2026년 분석 구간]

6년 전 저는 “크롤링을 할때는 항상 주의해주시구요”라는 한 줄로 끝냈습니다. 지금이라면 그 한 마디를 섹션 하나로 쓰겠습니다.

robots.txt와 이용약관이 먼저입니다

어느 사이트든 크롤링을 시작하기 전에 robots.txt를 확인하는 것이 출발점입니다. 크롤러에 대한 접근 허용·제한 범위가 명시된 경우가 많고, 이용약관도 함께 읽어두는 편이 좋습니다. 구체적인 법적 판단은 이 글의 범위를 벗어나지만, “확인하고 시작하는 것”과 “그냥 시작하는 것” 사이에는 분명한 차이가 있습니다.

랜덤 슬립은 그나마 잘한 선택이었습니다

매 스크롤과 다운로드마다 random.uniform(1,3) 슬립을 넣은 건 서버에 과도한 부하를 주지 않으려는 최소한의 배려였습니다. 6년이 지난 지금 기준에서 봐도 이 방향은 맞습니다.

다운받은 이미지의 저작권은 별개 문제입니다

크롤링으로 이미지를 수집했다고 해서 그 이미지를 자유롭게 쓸 수 있는 건 아닙니다. 학습·개인 실험 목적과 배포·상업적 활용은 다르게 봐야 합니다. 사용 목적에 따라 각 이미지의 라이선스를 별도로 확인하는 것이 필요합니다.

공식 API부터 먼저 봅니다

네이버는 검색 관련 Open API를 별도로 제공하고 있습니다. 크롤링을 시도하기 전에 공식 API가 있는지부터 확인하는 것이 더 좋은 순서입니다. 구체적인 엔드포인트, 파라미터, 일일 호출 한도는 네이버 Developers 공식 문서에서 직접 확인하시기를 권합니다. 이 글에서는 “공식 경로가 있다”는 사실만 남겨둡니다.


6. 6년 뒤의 점검 순서 — 같은 작업을 다시 한다면

[2026년 분석 구간]

지금 같은 작업을 다시 시작해야 한다면, 저는 이 순서로 접근합니다:

  1. 공식 API가 있는지부터 확인 — 네이버 검색 Open API처럼 공식 경로가 있다면 그쪽을 먼저 검토합니다
  2. 없다면 robots.txt와 이용약관 확인 — 허용 범위를 파악하는 게 코드보다 앞입니다
  3. Selenium 4.6.0 이상 기준으로 By 셀렉터 재작성find_element_by_* 계열은 현행 환경에서 동작하지 않을 가능성이 큽니다
  4. 셀렉터는 현재 페이지를 직접 열어 새로 잡기img._img가 지금도 유효한지 직접 확인이 필요합니다
  5. 슬립·재시도·예외 처리 구조는 그대로 유지 — 랜덤 슬립 설계는 지금 기준에서도 가져갈 만합니다

2020 vs 2026 — 변화 요약

항목2020년 원본2026년 시점 메모
Selenium 메서드find_element_by_css_selectorfind_element(By.CSS_SELECTOR, ...) 권장 (Selenium 공식 마이그레이션 가이드 기준)
ChromeDriver 관리./chromedriver 수동 경로 지정Selenium Manager 자동 관리 옵션 존재 (4.6.0 이상)
네이버 이미지 셀렉터img._img페이지 개편 가능성, 재조사 필요
접근 경로 우선순위검색 결과 페이지 직접 크롤링공식 Open API 우선 검토

마무리

원본 글은 솔직히 부끄러울 만큼 짧았습니다. 그때 던지듯 올렸던 코드 한 덩어리가 6년 뒤 회고의 출발점이 됐습니다. “크롤링을 할때는 항상 주의해주시구요”라는 한 줄이 이번엔 섹션 하나로 확장됐습니다. 짧고 거친 메모도 남겨두는 게 맞더라고요.


출처

  • 원본 학습 출처(유튜브): <https://www.youtube.com/watch?v=HJN28B7OSzw>
  • Selenium 공식 마이그레이션 가이드: <https://www.selenium.dev/documentation/webdriver/getting_started/upgrade_to_selenium_4/>
  • Selenium Manager 공식 문서: <https://www.selenium.dev/documentation/selenium_manager/>