1. 동적 요소 이해하기
동적 콘텐츠의 본질에 대해 간단히 알아보자. 웹사이트에 접속하여 페이지를 아래로 스크롤할 때마다 더 많은 데이터가 나타나는 모습을 상상해봐. 마치 끊임없이 확장하여 사용할 수 있는 마법의 양탄자 같아. 이를 "lazy loading"이라 불러, 필요할 때만 콘텐츠를 로드하여 자원을 절약하는 기술이야. 이런 경우 정적 HTML에 의존하는 건 아침 커피를 고양이가 가져다주길 바라는 것과 같아.
동적 요소란?
동적 요소는 페이지 전체를 새로 고침하지 않아도 변경될 수 있는 웹 페이지의 일부야. AJAX 요청을 통해 로드되거나 JavaScript를 통해 페이지에 삽입될 수 있어. 이런 요소를 다룰 수 있는 몇 가지 전략을 익히는 건 중요해, 왜냐하면 너의 애플리케이션이 콘텐츠만큼이나 동적이어야 하니까.
2. 상호작용 전략
이제 실전 마법을 시작하자! 동적 요소를 처리하려면 "삶은 움직임이며, 나는 준비되었다" 라는 걸 이해하는 도구가 필요해. 우리의 마법 도구에는 Selenium이 있어, Selenium은 브라우저와 사람처럼 상호작용할 수 있게 해줘.
AJAX 요청 작업하기
AJAX는 페이지 전체를 리로드하지 않고도 웹 페이지 일부를 업데이트할 수 있는 기술이야. 사용자에게는 편리하지만, 스크레이퍼 개발자에게는 약간 힘든 일이야. 하지만 우리에게는 비밀 무기인 Selenium의 WebDriverWait와 expected_conditions가 있어.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 드라이버 설정
driver = webdriver.Chrome()
driver.get("https://example-dynamic-site.com")
# 요소 나타나길 기다리기
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "dynamic_element_id"))
)
print(element.text)
finally:
driver.quit()
기다리는 방법 사용하기
동적 요소와 작업할 때 브라우저가 필요한 상태에 "도달"할 시간을 주는 게 중요해. WebDriverWait와 expected_conditions를 조합하여 모든 필요한 요소가 로드될 때까지 부드럽게 기다릴 수 있어. 이건 마치 헬스장에 가는 것과 같아—시간이 필요하지만 결과는 가치 있어.
예시:
-
presence_of_element_located— 요소가 DOM에 나타날 때까지 기다려. -
visibility_of_element_located— 요소가 보일 때까지 기다려. -
element_to_be_clickable— 요소가 클릭 가능할 때까지 기다려.
예를 들어, 버튼의 클릭 가능성을 기다리는 방법은 다음과 같아:
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[@id='submit']"))
)
button.click()
페이지 스크롤링
콘텐츠가 스크롤 시 로드되는 경우 "스크롤링" 기술이 필요해. Selenium을 사용하면 JavaScript를 사용해서 스크롤링을 구현할 수 있고, 이를 통해 새로운 데이터를 로드할 수 있어.
# 페이지 끝까지 스크롤
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
반복문에서 스크롤을 구현하여 모든 콘텐츠를 로드할 수 있어:
SCROLL_PAUSE_TIME = 2
driver.get("https://example.com/dynamic-content")
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 페이지가 콘텐츠를 로드할 시간을 기다려
WebDriverWait(driver, SCROLL_PAUSE_TIME)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
3. 상호작용의 실전 예제
이제 기다리고 관찰하는 방법을 배웠으니, 실전에 적용해서 동적 데이터를 모두 잡아보자.
예를 들어, 아래로 스크롤하면 로드되는 상품 페이지가 있다고 가정하자. 여기서 각 상품의 이름과 가격을 추출해야 해:
products = []
while True:
# 아래로 스크롤
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 새로운 요소 로드를 기다려
WebDriverWait(driver, SCROLL_PAUSE_TIME)
# 상품 데이터 추출
items = driver.find_elements(By.CLASS_NAME, "product-item")
for item in items:
name = item.find_element(By.CLASS_NAME, 'product-name').text
price = item.find_element(By.CLASS_NAME, 'product-price').text
products.append({'name': name, 'price': price})
# 새로운 것이 로드되었는지 확인
# (단순 확인: items 리스트의 크기가 증가하지 않으면 종료)
if len(products) == last_known_count:
break
last_known_count = len(products)
동적 요소가 우리가 원하는 만큼 빨리 로드되지 않을 때, 인내심과 요령이 필요해. WebDriverWait와 조건, 페이지 스크롤링, JavaScript 삽입은 동적 콘텐츠의 세계를 정복하는 열쇠야. 위대한 제다이가 말했듯이: "인내심을 가져라, 어린 파다완". 우리에게 인내는 모든 데이터를 크롤링하는 걸 의미해.
하루를 성공적으로 마무리하는 것처럼 세션을 종료하자.
driver.quit()
마지막으로: 코드가 정확하게 작동하고 오류 없이 실행되는지 확인하는 게 중요해. 이렇게 해야 "임무 완료"라고 자신 있게 말할 수 있어. 동적 데이터 세계를 탐험하는 너의 여정에 행운을 빌어!
GO TO FULL VERSION