Python 의 selenium 을 이용해서 스크롤 하기
크롤링 할 때 웹페이지를 스크롤 다운해야하는 경우가 있죠.
스크롤다운해서 끝까지 가야 그 다음 데이터를 조회하는 경우가 있고 그 외에도 필요한 경우가 있습니다.
방법 1. scrollTo
driver.execute_script("window.scrollTo(0, Y)")
여기서 Y 는 height 을 입력하면 됩니다.
페이지 끝까지 가려면 document.body.scrollHeight 를 사용합니다.
계속해서 스크롤 다운하면서 데이터를 다 조회할때는
SCROLL_PAUSE_SEC = 1
# 스크롤 높이 가져옴
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
# 끝까지 스크롤 다운
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# 1초 대기
time.sleep(SCROLL_PAUSE_SEC)
# 스크롤 다운 후 스크롤 높이 다시 가져옴
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
이 코드도 약간 문제가 있을 수 있는게, 로딩이 길게 걸릴땐 중간에 멈출수 있다는거죠.
이에대한 해결 방법은
1. SCROLL_PAUSE_SEC 을 늘리거나,
2. new_height 와 last_height 가 같을 때만 한번 더 sleep 하고 new_height 를 다시 가져와서 체크.
2번 방법이 나을듯합니다. 1번은 전체 크롤링 속도가 늦어질거니까요.
방법 2. ActionChains 의 move_to_element
이것은 특정한 element 를 알고 있을 때 그 위치까지 scroll 하게 됩니다.
예를들어
# ActionChains 를 사용하기 위해서.
from selenium.webdriver import ActionChains
# id가 something 인 element 를 찾음
some_tag = driver.find_element_by_id('something')
# somthing element 까지 스크롤
action = ActionChains(driver)
action.move_to_element(some_tag).perform()
코드에 'something' element를 찾았는지 체크를 하는게 좋겠습니다. if 문 하나 추가하시면 됩니다.
방법 3. 특정 시간동안 계속해서 scroll down 하기.
제가 사용하는 소스코드인데요.
아래와 같이 datetime 을 이용해서 정해진 초 동안 1초에 한번씩 스크롤 다운합니다.
이 방법은 무한로딩 데이터를 다 가져올 수 없으니 적당히 가져올때 사용합니다.
import datetime
def doScrollDown(whileSeconds):
start = datetime.datetime.now()
end = start + datetime.timedelta(seconds=whileSeconds)
while True:
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
time.sleep(1)
if datetime.datetime.now() > end:
break
예를들어 60초 동안 계속해서 스크롤 다운하려면 doScrollDown(60) 이렇게 쓰면 되겠네요.
1초에 한번씩 스크롤할 필요없으면 sleep 시간을 조정하면 됩니다.
크롤링 하려는 페이지에 특성에 맞게 scroll 하면서 데이터를 다 찾아내면 되겠습니다.
무한 스크롤
# 무한 스크롤
import time
SCROLL_PAUSE_TIME = 2
# Get scroll height
last_height = driver.execute_script("return document.body.scrollHeight") [1]
while True:
# Scroll down to bottom [2]
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Wait to load page
time.sleep(SCROLL_PAUSE_TIME) [3]
driver.execute_script("window.scrollTo(0, document.body.scrollHeight-50);") [4] time.sleep(SCROLL_PAUSE_TIME)
# Calculate new scroll height and compare with last scroll height [5]
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height: [6]
break last_height = new_height
[ 1 ] : 마지막 시점의 창 높이 저장
[ 2 ] : 창 높이까지 스크롤
[ 3 ] : 스크롤 후 창이 로딩될때까지 2초를 기다리겠다는 명령어. 로딩이 다되면 바로 넘어감
[ 4 ] : 한 번에 맨 마지막까지 스크롤되면 아래 리스트가 뜨지 않아서, 마지막을 찍고 조금 창을 올리는 방법으로 리스트가 로딩될 수 있게 함
[ 5 ] : 스크롤이 된 후의 창 높이를 새로운 높이로 저장
[ 6 ] : 새로운 높이가 이전 높이와 변하지 않았으면 스크롤 종료
'내마음대로만들어보자 > 참고자료' 카테고리의 다른 글
[참고자료] 자바스프링 기본개념 (0) | 2021.06.18 |
---|---|
[참고자료] 크롤링 (0) | 2021.06.11 |
[참고자료] 바닐라 자바스크립트 웹 프로젝트 소스 (0) | 2021.06.07 |