왓챠 무한 크롤링

Hyoeun·2022년 8월 13일
1
post-thumbnail

Dynamic Web Page

동일한 레이아웃과 디자인을 유지하면서 각각 다른 내용을 display하는 Web Page (https://www.packetlabs.net/posts/dynamic-pages)

  • 날씨, 주가, 시간 등의 정보 (실시간으로 변함)
  • Instagram, watcha, Facebook 등 (사용자가 스크롤을 내리면 새로운 정보 update)

2번째 부류의 crawling을 구현 (Watcha)

  • 정보를 충분히 가져올 때까지 스크롤을 계속 내린다.
  • 쌓여 있는 elements를 가져온다.

여기서 충분한 정보를 영화 1000개라고 가정하였고(너무 많이 가져 올 시 Memory 이슈 발생), 따라서 1000개의 영화가 쌓일 때까지 계속 스크롤을 내려야 했다.
영화 1000개가 쌓일 때까지 최대한 빠르게 스크롤을 내릴 방법을 생각해야 했는데 한번 내린 후 적절한 time.sleep()을 주는 방법밖에 떠오르지 않아 다른 방법을 찾아 보았다.

  1. https://stackoverflow.com/questions/32888967/infinite-scroll-on-quora-using-selenium-in-python-and-javascript
  2. https://betterprogramming.pub/infinite-scrolling-with-selenium-c25808c16993

첫 번째 방법은 내가 찾고 싶은 element의 개수를 정한 뒤 그 개수만큼 정보가 쌓일 때까지 계속 스크롤을 내리는 방법이다.

num_movies = 0
while num_movies < 1000:
    driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
    num_movies = len(driver.find_elements_by_class_name("css-8y23cj"))

두 번째 방법은 Web Page의 height를 기반으로 한다.
현재 Page의 height를 저장하고, 스크롤을 내린 후 new_height > last_height를 충족할 때까지 Explicit wait한다.

class infine_scroll(object):
  def __init__(self, last):
    self.last = last

  def __call__(self, driver):
    new = driver.execute_script('return document.body.scrollHeight')  
    if new > self.last:
        return new
    else:
        return False
        
last_height = driver.execute_script('return document.body.scrollHeight')
flag=1
while flag==1:
	driver.execute_script('window.scrollTo(0,document.body.scrollHeight);')
	try:
  		wait = WebDriverWait(driver, 10)
  		new_height = wait.until(infinite_scroll(last_height))
        last_height = new_height

	except:
    	print("End of page reached")
    	flag = 0

첫 번째 방법으로 진행 시 1000개의 영화를 가져오는 데에 약 13분이 걸렸지만
두 번째 방법을 이용하니 약 8분 30초만에 더 이상 정보가 update 되지 않을 때까지 스크롤을 내렸고 무려 4200개의 영화를 가져왔다.
(두 방법 모두 무선 LAN 환경에서 진행되었음)

Conclusion

  • time.sleep()을 주는 것에 비해 첫 번째 방법 또한 효율적으로 보이지만 실제로는 그렇지 않고, 두 번째 방법의 효율이 몇 배는 더 좋음.
  • 두 번째 방법은 End Of Page를 만날 때까지 계속 되는데,
while True:
	try:
    	driver.execute_script('window.scrollTo(0,document.body.scrollHeight);')
    except:
    	break
  • 이러한 방법을 쓰지 않는 것은 최대한의 효율성을 위한 것일까?
  • 정보가 너무 많을 시엔 Memory Issue 등에 대한 대처가 필요할 듯

0개의 댓글