클릭, 스크롤, 페이지 이동, 요소 탐색까지 웹페이지를 “직접 조작”하는 자동화 도구
Selenium은 단순히 HTML을 받아와서 파싱하는 도구가 아닙니다.
Selenium은 브라우저를 실제로 열고, 사람이 하듯이 페이지를 조작하면서 데이터를 수집하는 도구입니다.
이 점이 requests + BeautifulSoup와 가장 큰 차이입니다.
requests + BeautifulSoup는 주로:
- 서버에 요청해서
- HTML을 받아오고
- 그 HTML 안의 구조를 읽는 방식
이었다면,
Selenium은:
- 브라우저를 실행하고
- 페이지를 열고
- 버튼을 클릭하고
- 스크롤을 내리고
- 페이지를 넘기고
- 동적으로 로딩된 요소를 기다린 뒤
- 화면에 실제로 나타난 데이터를 가져오는 방식
입니다.
즉, Selenium은
“웹페이지를 읽는 것”을 넘어서 “웹페이지를 조작하는 것” 에 강합니다.
이 파트를 이해하면 다음 상황에 대응할 수 있게 됩니다.
- 페이지에 버튼 클릭이 필요한 경우
- 스크롤을 내려야 데이터가 더 뜨는 경우
- 검색어 입력 후 결과가 갱신되는 경우
- 드롭다운 선택으로 목록이 바뀌는 경우
- JavaScript가 실행된 뒤에야 데이터가 보이는 경우
- 페이지 번호를 눌러 다음 목록으로 넘어가야 하는 경우
즉, Selenium은 특정 프로젝트 전용 도구가 아니라,
동적 웹페이지 자동화 전반에 쓰이는 범용적인 핵심 도구입니다.
1. Selenium은 왜 필요한가?
웹 크롤링을 하다 보면 requests + BeautifulSoup만으로는 안 되는 페이지를 자주 만납니다.
예를 들면 이런 경우입니다.
- 처음 HTML에는 매물 데이터가 거의 없음
- JavaScript가 실행된 뒤에 데이터가 채워짐
- “더보기” 버튼을 눌러야 추가 목록이 나타남
- 무한 스크롤이라 아래로 내려야 다음 데이터가 보임
- 검색 필터를 클릭해야 원하는 목록이 바뀜
- 로그인이나 팝업 닫기 같은 사용자 동작이 필요함
이런 페이지는 그냥 HTML 한 번 받아오는 방식으로는 부족할 수 있습니다.
즉, Selenium은
정적인 문서 수집이 아니라, 사용자 행동이 필요한 웹페이지를 다루기 위해 등장하는 도구입니다.
2. Selenium의 핵심 개념
Selenium을 처음 배울 때는 복잡해 보일 수 있지만, 핵심은 단순합니다.
Selenium은 크게 보면 다음 흐름으로 작동합니다.
- 브라우저를 실행한다
- 원하는 URL로 이동한다
- 페이지 안의 요소를 찾는다
- 클릭, 입력, 스크롤 같은 동작을 수행한다
- 결과가 바뀌면 다시 요소를 찾는다
- 텍스트나 속성 값을 추출한다
즉, Selenium은
브라우저 자동화 + 요소 탐색 + 데이터 추출
세 가지를 묶은 도구라고 보면 됩니다.
3. WebDriver란 무엇인가?
3-1. 정의
Selenium에서 브라우저를 제어하는 핵심 객체를 보통 WebDriver라고 부릅니다.
쉽게 말하면:
브라우저를 조종하는 리모컨 같은 역할
입니다.
예를 들어 크롬 브라우저를 띄우고 제어하려면 보통 Chrome WebDriver를 사용합니다.
3-2. 왜 중요한가?
우리가 Selenium으로 하는 모든 행동은 결국 WebDriver를 통해 이루어집니다.
예:
- 페이지 열기
- 현재 URL 확인
- 요소 찾기
- 클릭
- 입력
- 스크롤
- 종료
즉, WebDriver는 Selenium의 중심입니다.
4. Selenium 기본 실행 구조
가장 기본적인 예시는 이런 식입니다.
이 코드의 의미는 다음과 같습니다.
- webdriver.Chrome() → 크롬 브라우저를 자동 실행
- driver.get(url) → 해당 URL로 이동
즉, 이 두 줄만으로도
“브라우저를 열고 페이지로 이동한다”는 가장 기본 동작이 이루어집니다.
5. driver는 무엇인가?
Selenium 예제에서 거의 항상 driver라는 이름이 등장합니다.
예:
여기서 driver는
브라우저를 제어하는 객체를 담고 있는 변수입니다.
즉, driver를 통해:
- 페이지 이동
- 요소 찾기
- 클릭
- 입력
- 종료
를 하게 됩니다.
예:
즉, driver는 Selenium 코드의 중심 조작 도구입니다.
6. 페이지 열기: get()
6-1. 정의
get()은 브라우저를 특정 URL로 이동시키는 메서드입니다.
예:
이건 사람이 주소창에 URL을 입력하고 엔터를 누른 것과 비슷합니다.
6-2. 왜 중요한가?
모든 크롤링과 자동화는 결국 “어느 페이지를 열 것인가”에서 시작합니다.
즉:
- 목록 페이지 열기
- 상세 페이지 열기
- 검색 결과 페이지 열기
같은 작업이 다 get()에서 시작됩니다.
7. 페이지 정보 확인하기
Selenium으로 페이지를 열면 현재 페이지 정보도 확인할 수 있습니다.
7-1. 현재 제목
페이지 제목을 보여줍니다.
7-2. 현재 URL
현재 브라우저가 어느 URL에 있는지 보여줍니다.
7-3. 페이지 소스 보기
print(html[:500])
이건 현재 브라우저에 렌더링된 HTML 소스를 문자열로 가져옵니다.
중요한 점은 driver.page_source는
브라우저가 실행된 뒤 시점의 HTML 이라는 것입니다.
즉, requests로 받은 초기 HTML과 다를 수 있습니다.
JavaScript가 실행되어 DOM이 바뀐 후의 HTML을 볼 수 있다는 점이 Selenium의 큰 장점 중 하나입니다.
8. 요소(element)란 무엇인가?
Selenium에서는 페이지 안의 버튼, 입력창, 제목, 카드 하나하나를 보통 요소(element) 라고 부릅니다.
예:
- 버튼 하나
- 검색창 하나
- 가격 span 하나
- 차량 카드 div 하나
이런 것이 모두 요소입니다.
즉, Selenium은 결국
원하는 요소를 찾아서 조작하거나 읽는 일이라고 이해하면 됩니다.
9. 요소 찾기: find_element() / find_elements()
9-1. 하나 찾기
이건 조건에 맞는 요소 하나를 찾습니다.
9-2. 여러 개 찾기
이건 조건에 맞는 요소 여러 개를 리스트처럼 찾습니다.
9-3. 왜 중요한가?
이건 BeautifulSoup의:
- find()
- find_all()
과 감각이 비슷합니다.
즉:
- 하나의 버튼을 찾을 때 → find_element
- 반복되는 카드 목록을 찾을 때 → find_elements
를 쓰게 됩니다.
10. 요소를 어떤 기준으로 찾을까? By
Selenium에서는 요소를 찾을 때 무슨 기준으로 찾을지를 명시합니다.
이때 자주 쓰는 것이 By입니다.
예:
그리고 다음처럼 씁니다.
즉:
- By.CLASS_NAME → class 기준
- "price" → 실제 class 이름
입니다.
11. 자주 쓰는 요소 탐색 기준
11-1. By.ID
id 기준으로 찾습니다.
11-2. By.CLASS_NAME
class 기준으로 찾습니다.
주의할 점은 여러 class가 공백으로 묶인 경우 전체를 그대로 넣는 방식은 조심해야 합니다.
11-3. By.TAG_NAME
태그 이름 기준입니다.
모든 링크 태그를 찾을 수 있습니다.
11-4. By.CSS_SELECTOR
CSS 선택자를 씁니다.
이건 매우 강력하고 자주 쓰입니다.
11-5. By.XPATH
XPath라는 경로 표현 방식으로 찾습니다.
XPath는 강력하지만 처음엔 다소 낯설 수 있습니다.
처음엔 CSS selector 중심으로 익히고, 필요할 때 XPath를 배우는 것도 좋습니다.
12. CSS Selector와 XPath는 어떻게 이해하면 좋을까?
CSS Selector
- 웹 구조 감각과 자연스럽게 연결됨
- 읽기 쉬운 경우가 많음
- 크롤링과 프론트 감각을 함께 키우기 좋음
예:
XPath
- 트리 구조를 아주 세밀하게 지정 가능
- 특정 조건 탐색에 강한 경우가 있음
- 복잡한 구조에서 유용할 수 있음
예:
어떻게 선택하면 좋을까?
처음에는 CSS selector부터 익히는 것이 보통 더 직관적입니다.
하지만 어떤 페이지에서는 XPath가 더 편할 수 있으므로, 둘 다 존재를 알고 있어야 합니다.
즉, 중요한 건 도구 이름보다
“원하는 요소를 안정적으로 찾을 수 있는가” 입니다.
13. 요소에서 텍스트 추출하기
요소를 찾았으면 그 안의 텍스트를 가져와야 합니다.
예:
print(price.text)
이렇게 하면 화면에 보이는 텍스트를 가져옵니다.
즉, Selenium의 .text는
BeautifulSoup의 .get_text()와 비슷한 역할을 한다고 이해할 수 있습니다.
14. 속성 값 가져오기: get_attribute()
텍스트만 가져오는 게 아니라 속성 값도 자주 가져옵니다.
예:
print(link.get_attribute("href"))
이건 링크 주소를 가져옵니다.
또 예를 들어:
print(img.get_attribute("src"))
이건 이미지 주소를 가져옵니다.
즉, Selenium에서도:
- 텍스트 추출
- 속성 추출
둘 다 중요합니다.
15. 클릭하기: click()
Selenium이 requests + BeautifulSoup와 크게 다른 지점 중 하나가 바로 클릭입니다.
예:
button.click()
이 코드는 다음 페이지 버튼을 실제로 누르는 것과 비슷한 동작을 합니다.
클릭이 중요한 이유
실제 웹페이지에서는:
- 더보기 버튼
- 다음 페이지 버튼
- 탭 전환 버튼
- 필터 버튼
- 팝업 닫기 버튼
같은 것이 매우 자주 등장합니다.
즉, Selenium은
사람이 하는 클릭 행동을 자동화할 수 있다는 점이 매우 강력합니다.
16. 입력하기: send_keys()
검색창이나 로그인 창처럼 텍스트를 입력해야 하는 경우도 많습니다.
예:
search_box.send_keys("현대 아반떼")
이건 사람이 키보드로 검색어를 입력하는 것과 비슷합니다.
추가로 자주 쓰는 것: 입력값 비우기
search_box.send_keys("기아 K5")
즉, 기존 내용을 지우고 새로 입력할 수 있습니다.
17. 엔터 입력하기
검색창에 입력 후 엔터를 눌러야 할 때도 있습니다.
예:
search_box.send_keys("중고차")
search_box.send_keys(Keys.ENTER)
이렇게 하면 검색 버튼 클릭 없이 엔터 입력 효과를 줄 수 있습니다.
18. 여러 요소를 반복 처리하기
BeautifulSoup 때와 마찬가지로 Selenium에서도 목록형 구조가 매우 중요합니다.
예:
for item in items:
brand = item.find_element(By.CSS_SELECTOR, ".brand").text
price = item.find_element(By.CSS_SELECTOR, ".price").text
print(brand, price)
이건:
- .car-item 카드들을 여러 개 찾고
- 각 카드 안에서 브랜드와 가격을 추출합니다.
이 구조는 중고차 목록뿐 아니라:
- 상품 리스트
- 뉴스 기사 리스트
- 채용 공고 리스트
- 부동산 매물 리스트
등 거의 모든 목록형 동적 페이지에 응용됩니다.
19. 페이지 넘기기
동적 사이트에서는 다음 페이지로 이동해야 하는 경우가 많습니다.
예:
next_button.click()
이후에는:
- 페이지가 바뀌었는지
- 목록이 갱신되었는지
- 다시 요소를 찾아야 하는지
를 고려해야 합니다.
즉, 페이지 넘기기는 단순 클릭이 아니라
“클릭 후 새로운 화면 상태를 반영해 다시 탐색한다” 는 흐름까지 포함합니다.
20. 스크롤하기
일부 사이트는 스크롤을 내려야 데이터가 더 로딩됩니다.
이건 무한 스크롤 페이지에서 특히 중요합니다.
예:
이건 페이지 맨 아래로 스크롤합니다.
왜 중요한가?
요즘 많은 웹페이지는 처음에 전체 데이터를 다 보여주지 않습니다.
예:
- 아래로 내려야 다음 카드 로딩
- 일정 높이까지 내려야 광고/팝업 처리
- 스크롤 이벤트로 JavaScript가 실행됨
즉, 스크롤도 Selenium에서 매우 중요한 제어 동작입니다.
21. JavaScript 실행: execute_script()
Selenium은 브라우저 안에서 JavaScript를 직접 실행할 수도 있습니다.
예:
또는 요소를 클릭이 잘 안 될 때:
이런 식으로 우회하기도 합니다.
즉, Selenium은 단순 클릭 도구가 아니라
브라우저 내부 동작까지 직접 제어할 수 있는 자동화 도구입니다.
22. 대기(wait)가 왜 중요한가?
Selenium은 브라우저를 조작하지만,
웹페이지는 항상 즉시 로딩되지 않습니다.
즉, 버튼을 눌렀다고 해서
바로 다음 요소가 나타난다는 보장이 없습니다.
이때 자주 생기는 문제가:
- 요소를 찾으려 했는데 아직 안 뜸
- 페이지 전환은 됐는데 DOM 갱신 전임
- 비동기 로딩 중인데 코드는 너무 빨리 다음 단계로 감
입니다.
그래서 Selenium에서는 대기(wait) 개념이 매우 중요합니다.
이 파트에서는 개념 중심으로 이해하고,
더 자세한 대기 처리와 예외 처리는 다음 파트에서 깊게 다룰 수 있습니다.
23. 암시적 대기(Implicit Wait) 개념
예:
이건 요소를 찾을 때 최대 5초 정도 기다리겠다는 의미입니다.
즉, 페이지 로딩이 조금 느려도
바로 실패하지 않고 기다릴 수 있습니다.
24. 명시적 대기(Explicit Wait) 개념
특정 조건이 만족될 때까지 기다리는 방식입니다.
예:
- 버튼이 클릭 가능해질 때까지 기다리기
- 특정 요소가 화면에 나타날 때까지 기다리기
- 텍스트가 변경될 때까지 기다리기
이건 실전에서 훨씬 더 강력하고 중요합니다.
다음 파트에서 예외 처리와 함께 더 자세히 보는 것이 자연스럽습니다.
25. Selenium에서 자주 만나는 예외 상황
Selenium은 강력하지만 그만큼 자주 에러도 만납니다.
예:
- 요소를 못 찾음
- 클릭하려는데 가려져 있음
- 페이지가 덜 로딩됨
- 이전 페이지 요소를 계속 들고 있어서 stale element 발생
- 팝업 때문에 뒤 요소를 못 누름
즉, Selenium은 단순히 “클릭하는 코드”가 아니라
페이지 상태 변화까지 고려해야 하는 도구입니다.
이 점이 requests + BeautifulSoup보다 더 복잡한 이유입니다.
26. requests + BeautifulSoup와 Selenium 차이 다시 정리
requests + BeautifulSoup
- HTML을 요청해 가져옴
- 빠르고 가벼움
- 정적 페이지에 강함
- 브라우저를 실제로 열지 않음
Selenium
- 브라우저를 실제로 열고 조작함
- 클릭, 입력, 스크롤 가능
- 동적 페이지에 강함
- 상대적으로 느리고 무거움
즉, Selenium은 BeautifulSoup의 대체재가 아니라
필요한 상황이 다른 도구입니다.
27. Selenium이 범용적으로 중요한 이유
Selenium은 특정 사이트 크롤링에만 쓰는 도구가 아닙니다.
범용적으로 다음 영역까지 확장됩니다.
- 쇼핑몰 자동화
- 로그인 자동화
- 검색 자동화
- 뉴스/부동산/중고차 목록 수집
- 웹 테스트 자동화
- 폼 자동 입력
- 브라우저 반복 작업 자동화
- QA 테스트
- 사내 업무 자동화
즉, Selenium은
웹페이지를 자동으로 다루는 전반적인 도구라고 이해해야 합니다.
28. 기본적인 Selenium 흐름 예시
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com")
items = driver.find_elements(By.CSS_SELECTOR, ".car-item")
cars = []
for item in items:
brand = item.find_element(By.CSS_SELECTOR, ".brand").text
price = item.find_element(By.CSS_SELECTOR, ".price").text
cars.append({
"brand": brand,
"price": price
})
print(cars)
driver.quit()
이 코드 안에는 Selenium의 가장 기본적인 흐름이 들어 있습니다.
- 브라우저 열기
- 페이지 이동
- 요소 여러 개 찾기
- 반복문으로 돌기
- 하위 요소 텍스트 추출
- 결과 저장
- 브라우저 종료
이 흐름을 이해하면 다른 사이트에도 쉽게 응용할 수 있습니다.
29. 브라우저 종료하기: quit()
예:
이건 브라우저를 완전히 종료합니다.
왜 중요할까요?
- 테스트 중 브라우저가 계속 쌓이지 않게 하기 위해
- 자원 낭비를 막기 위해
- 프로세스를 깔끔하게 정리하기 위해
즉, Selenium에서는 시작만큼 종료도 중요합니다.
30. 범용적으로 꼭 익혀야 하는 Selenium 사고방식
30-1. 페이지는 “상태(state)”가 바뀐다
requests + BeautifulSoup는 보통 한 번 받은 HTML을 보는 느낌이 강합니다.
반면 Selenium은 클릭, 입력, 스크롤 후에 페이지 상태가 바뀝니다.
즉, Selenium에서는 항상:
- 지금 어떤 상태인가
- 클릭 후 무엇이 바뀌었나
- 새로 다시 찾아야 하나
를 생각해야 합니다.
30-2. 큰 구조 먼저, 세부 요소 나중
반복되는 카드 목록을 먼저 찾고,
그 안에서 브랜드/가격/링크를 찾는 방식이 안정적입니다.
30-3. 바로 찾지 말고 “언제 나타나는지”도 생각해야 한다
동적 페이지에서는 요소 존재 여부뿐 아니라
등장 시점도 중요합니다.
즉, Selenium은 단순 탐색이 아니라 시간 개념이 들어갑니다.
30-4. 눈에 보인다고 바로 가져올 수 있는 것은 아니다
때로는:
- 팝업이 가리고 있거나
- iframe 안에 있거나
- 로딩이 덜 끝났거나
- 스크롤 후에야 활성화될 수 있습니다
즉, Selenium은 항상 화면 상태 + DOM 상태 + 타이밍을 함께 봐야 합니다.
'AI > Python' 카테고리의 다른 글
| 크롤링 안정화: 대기 처리, 예외 처리, 매너 (0) | 2025.06.02 |
|---|---|
| 웹 크롤링 기초: requests + BeautifulSoup 관점 (0) | 2025.05.29 |
| 웹의 구조 이해: HTML / CSS / DOM (0) | 2025.05.28 |
| 데이터 저장 관점과 CSV / JSON / Excel 구조 이해 (0) | 2025.05.26 |
| 파이썬 파일 입출력과 모듈 구조 (0) | 2025.05.21 |