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개 크롤링하는 시간을
측정해서 비교해보겠습니다.
하지만 상황에 따라서 이 암묵적 대기(implicitly_wait)로 해결되지 않는 경우가 있습니다.
지금 예제에서는 운 좋게(?) implicitly_wait() 함수로 모든게 깔끔하게 해결되었지만,
이 다음 포스팅에서 그렇지 않는 경우를 한번 보겠습니다.
이 경우엔 명시적 대기(explicitly_wait)로 해결해줄 수 있습니다.
다음 포스팅에서 명시적 대기(explicitly_wait)에 대해 설명하겠습니다.
👉 파이썬 튜터 손원준 강의 링크
✔️ [온라인 Live 강의] taling.me/Talent/Detail/4466
✔️ [VOD 강의] taling.me/vod/view/31196
'파이썬 Tip' 카테고리의 다른 글
파이썬, 파이참 완벽 설치법 (윈도우 & 맥) (2) | 2023.06.01 |
---|---|
[챗봇] 파이썬 텔레그램 챗봇, 이것만 따라하면 20분 완성 (코로나 알리미 봇) (8) | 2021.03.13 |
[텍스트마이닝] Konlpy 모듈 완벽 설치법 (Windows, Mac) (1) | 2021.03.12 |
[PyCharm] 파이참 완전 편한 단축키 15개 깔끔 정리 (13) | 2021.02.21 |