본문 바로가기

파이썬 Tip

[Selenium] 실행 속도 높이기 #1 (암묵적 대기 Implicitly Wait)

selenium 사용해 본 사람이라면, 누구나 느끼는 답답한 점이 하나 있는데..

바로.. time.sleep() .....

이 글을 보시는 분이시라면,

time.sleep()이 왜 문제가 되는지, 충분히 이해하실 거라 생각합니다.

 

세 문장으로 정리하자면..

1. time.sleep()을 어디에 넣어야 하는지 잘모르겠어요!

1. time.sleep() 때문에 실행속도가 너무 느려져요!

2.time.sleep()을 몇 초로 설정 해야될지 모르겠어요!

 

이 세 가지 문제를 한 번에 해결해주는 것이 있습니다.

 

바로 암묵적 대기(implicitly wait)와 명시적 대기(explicitly wait) 라는 것!

 

쉽게 말해, time.sleep() 함수의 업그레이드 버전이라고 생각하시면 좋을 것 같아요.

 

우리가 불편을 느끼던 느린 실행 속도와 지연 시간 설정 문제를 모두 해결해 줍니다.

 

암묵적 대기(implicitly wait)

네이버 카페 게시글들을 크롤링하는 코드를 예제로 설명하겠습니다.

일단은 time.sleep() 을 적절한 곳에 넣어서 짠 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
 
keyword = '파이썬'
 
browser = webdriver.Chrome('./chromedriver')
 
url = 'https://search.naver.com/search.naver?query={}&nso=so&where=article&sm=tab_viw.all'.format(keyword)
browser.get(url)
time.sleep(2)
article_num = 1
while True:
    article = browser.find_element_by_css_selector('ul.lst_total > li.bx:nth-child({}) a.api_txt_lines.total_tit'.format(article_num))   # nth-child 를 이용해, article 들을 하나씩 차례대로 가져옵니다.
    ################ 크롤링 ###################
    # 게시글 제목
    title = browser.find_element_by_css_selector('ul.lst_total > li.bx:nth-child({}) a.api_txt_lines.total_tit'.format(article_num)).text
    # 카페 이름
    cafe = browser.find_element_by_css_selector('ul.lst_total > li.bx:nth-child({}) a.sub_txt.sub_name'.format(article_num)).text
    # 게시글로 이동
    article.click()
    time.sleep(3)
    # 탭 바꾸기
    last_tab = browser.window_handles[-1]
    browser.switch_to.window(last_tab)
    browser.switch_to.frame('cafe_main')
    # 게시글
    paragraph = browser.find_element_by_css_selector('div.article_viewer').text
 
    print("제목 :", title)
    print("내용 :", paragraph)
    print()
    ##############################################
 
    browser.close()
    last_tab = browser.window_handles[-1]
    browser.switch_to.window(last_tab)
 
    if article_num % 10 == 0:  # article들이 10개씩 load 되므로, article_num이 10의 배수일때마다 스크롤을 내려줍니다.
        browser.find_element_by_css_selector("html").send_keys(Keys.END)
        time.sleep(3)
    article_num += 1
cs

11번째, 22번째, 41번째 줄에 time.sleep()이 들어가 있습니다.

 

위 코드를 실행해보면,

time.sleep() 때문에 크롤링 속도가 상당히 느린 것을 볼 수 있죠.

 

또, 이 프로그램을 처음부터 코딩한다면,

time.sleep()을 어떤 위치에 넣어야 하는지 감이 잘 오지 않을 수 있습니다.

 

이 때, 명시적 대기를 한번 사용해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
 
keyword = '파이썬'
 
browser = webdriver.Chrome('./chromedriver')
browser.implicitly_wait(3)
url = 'https://search.naver.com/search.naver?query={}&nso=so&where=article&sm=tab_viw.all'.format(keyword)
browser.get(url)
article_num = 1
while True:
    article = browser.find_element_by_css_selector('ul.lst_total > li.bx:nth-child({}) a.api_txt_lines.total_tit'.format(article_num))   # nth-child 를 이용해, article 들을 하나씩 차례대로 가져옵니다.
    ################ 크롤링 ###################
    # 게시글 제목
    title = browser.find_element_by_css_selector('ul.lst_total > li.bx:nth-child({}) a.api_txt_lines.total_tit'.format(article_num)).text
    # 카페 이름
    cafe = browser.find_element_by_css_selector('ul.lst_total > li.bx:nth-child({}) a.sub_txt.sub_name'.format(article_num)).text
    # 게시글로 이동
   article.click()
    # 탭 바꾸기
    last_tab = browser.window_handles[-1]
    browser.switch_to.window(last_tab)
    browser.switch_to.frame('cafe_main')
    # 게시글
    paragraph = browser.find_element_by_css_selector('div.article_viewer').text
 
    print("제목 :", title)
    print("내용 :", paragraph)
    print()
    ##############################################
 
    browser.close()
    last_tab = browser.window_handles[-1]
    browser.switch_to.window(last_tab)
 
    if article_num % 10 == 0:  # article들이 10개씩 load 되므로, article_num이 10의 배수일때마다 스크롤을 내려줍니다.
        browser.find_element_by_css_selector("html").send_keys(Keys.END)
    article_num += 1
cs

time.sleep()을 전부 없애고,

browser.implicitly_wait() 를 8번째줄에 추가하였습니다.

 

이렇게 하면 크롤링 속도가 최소 3~4배는 빨라진 것을 볼 수 있습니다.

time.sleep()을 어디 넣을지 신경쓸 필요도 없어지죠!

 

implicitly_wait() 함수를 딱 한번만 써주게 되면, 

"암묵적 대기"를 설정해줄 수 있게 됩니다.

 

예를 들어, browser.implicitly_wait(3) 이라고 하게 되면,

컴퓨터에게 이렇게 명령하는 거죠!

 

"컴퓨터야 코드 쭉~ 실행하다가,

find_element_by_css_selector() 함수에서

내가 말한 요소가 없으면

우선 에러 뱉지 말고,

딱 3초만 기다려봐~"

 

오, 뭔가 우리가 원하던 딱 그런 명령을 한 문장으로

해결할 수 있으니 되게 좋은 것 같죠!

 

한번 카페 게시글 100개 크롤링하는 시간을 

측정해서 비교해보겠습니다.

딱 3배 정도 크롤링 속도가 빨라진 것을 볼 수 있습니다.

하지만 상황에 따라서 이 암묵적 대기(implicitly_wait)로 해결되지 않는 경우가 있습니다.

지금 예제에서는 운 좋게(?) implicitly_wait() 함수로 모든게 깔끔하게 해결되었지만,

이 다음 포스팅에서 그렇지 않는 경우를 한번 보겠습니다.

 

이 경우엔 명시적 대기(explicitly_wait)로 해결해줄 수 있습니다.

다음 포스팅에서 명시적 대기(explicitly_wait)에 대해 설명하겠습니다.

 

 

 

👉 파이썬 튜터 손원준 강의 링크

✔️ [온라인 Live 강의] taling.me/Talent/Detail/4466

 

[선착순 2명 남음] 코딩으로 회사에서 '에이스'되기 #파이썬 | 탈잉

——————— 공 지 사 항 ——————— ✔️ 심화반 OPEN! (기본반 / 심화반 선택 가능) ✔️ 기본반 / 심화반 커리큘럼 확인 필수! ✔️ 온라인 Live 수업 (3시간씩 4회 일정) ✔️ 수업 날짜 -

taling.me:443

✔️ [VOD 강의] taling.me/vod/view/31196

 

직장인을 위한 파이썬 기초

스마트한 업무의 필수 조건

taling.me