셀레니움 팝업창 닫기 - sellenium pab-eobchang dadgi

셀레니움을 이용해서 웹브라우저 자동화를 만들때에 예상치 못합 팝업창이 떠서 내가 생각한 자동화 로직이 깨질때가 있습니다. 이럴 때는 팝업창을 감지해서 팝업창을 닫아줘야 합니다. 요즘은 팝업창이 자주 발생하지는 않지만

새로운 팝업창 감지는 WebDriverWaitexpected_conditions를 통해서 알 수 있습니다. 해당 기능을 통해서 페이지의 로딩, 경고창 등 역시 감지 할 수 있습니다.

먼저 새로운 팝업을 알아내려면 이전까지의 브라우저 handles을 알아야 합니다. 팝업이란 것 역시 새로운 창 handle이기 때문입니다.

browser = webdriver.Chrome(ChromeDriverManager().install())
tabs = browser.window_handles

이렇게 하면 현재 열려있는 브라우저의 탭을 가져올 수 있습니다. tabs는 리스트이며, 현재 탭이 2개라면 2개의 핸들이 들어있게 됩니다.

셀레니움 팝업창 닫기 - sellenium pab-eobchang dadgi
셀레니움 팝업창 닫기 - sellenium pab-eobchang dadgi

이렇게 탭이 2개 일 경우 코드를 실행하면 리스트로 된 탭 값을 얻을 수 있습니다.

#이전 까지의 핸들리스트를 넣어준다. 따로 저장을 해두던지 지정한 코드 전에 현재 핸들로 체크한다.
window_handles = browser.window_handles

# ...자동화 코드 실행...

# 팝업이 있는지 체크
new_popup = WebDriverWait(browser, 2).until(EC.new_window_is_opened(window_handles))

새로운 팝업, 탭이 오픈이 된 것은 expected_conditions을 통해서 알 수 있다고 했습니다. 조건은 new_window_is_opened입니다. 여기에는 이전 핸들리스트를 넣어주면됩니다. 저는 카페 가입을 하고나서 가입 인사 팝업이 발생하여서 해당 코드를 추가했습니다. 최초에 설정한 핸들 리스트를 저장해두고 코드 실행 후 팝업 체크때 사용했습니다.

current_handle = browser.current_window_handle;
browser.switch_to.window('새로운 팝업 핸들')
browser.close()
browser.switch_to.window(current_handle)

current_window_handle로 현재 브라우저 핸들을 저장해 두고 팝업의 핸들을 찾아서 전환한 다음 close()를 실행하여서 종료시킵니다. 그리고 나서 저장해둔 현재 핸들로 전환 후 원하는 코드를 실행 하면 됩니다.

2020 04 19 

1) 시간창 대기 3가지 

보통 시간창 대기는 time.sleep , implicity_wait , Explicit Waits 3가지를 씁니다. 

time.sleep 은 그냥 지정한 시간만큼 기다린 뒤에 작업을 진행. 파이썬 내장 모듈이죠. 

implicitly_wait 는 지정한 시간만큼 기다려주고 그 이후는 기다리지 않습니다. 

Explicit Waits 는 특정 상태가 될때까지 기다리고, 상태가 되면 바로 실행한다는 의미입니다. 

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('./chromedriver')

# 무조건 지정된 time만큼 대기 
#time.sleep(10)

# 10초까지 기다려준다. 10초 안에 웹 화면이 표시되면 바로 다음 작업이 진행됨 
driver.implicitly_wait(10)

driver.get('https://naver.com')

# button = driver.find_element_by_css_selector('#search_btn')

# 검색 버튼을 찾아서 누를건데, 최대 5초까지만 기다리겠다라는 의미 
button = WebDriverWait(driver,5).until(EC.presence_of_element_located((By.CSS_SELECTOR, '#search_btn')))
button.click()

2) 팝업창 닫기 

요즘 사이트들은 팝업창 뜨는 사이트들은 많지 않다고 하는데

내가 크롤링하려는 곳이 팝업창이 있을 수도 있으니 익혀두는 게 좋을 것 같습니다.

우선, 바로 코드 먼저 보시죠. 

핵심은 window_handles 입니다. 

 새로운 탭을 열고 로딩을 기다린뒤 윈도우 목록을 확인해보면 여러 개의 항목이 들어있는 것을 볼 수 있습니다.

셀레니움 팝업창 닫기 - sellenium pab-eobchang dadgi
메인창과 팝업창이 3개여서 목록 안의 4개의 값이 들어가 있습니다.

제가 참고한 강의에서는 팝업창이 하나만 떴는데 

제가 실습을 하는 20200419 1800 기준으로는 팝업창이 3개였습니다. { 참고한 동영상과 같은 사이트입니다 :)  }

그래서 반복문을 써서 close 시켜주었습니다. 

switch_to_window 함수는 이름 그대로입니다. 

메인으로 선택하는 윈도우 창을 바꿔주는 메서드입니다. 

그러니깐 저희가 여러 개의 팝업창이 떠있어도 선택된 창은 하나 잖아요?

그런 걸 의미합니다 :) 

# pop up 창 닫기 

from selenium import webdriver
import time

url = 'http://www.lottemart.com'
driver = webdriver.Chrome('./chromedriver')
driver.get(url)

# 팝업창 만큼 요소가 늘어나는 걸 확인할 수 있음. 
print(driver.window_handles)

time.sleep(8)
# 팝업창 1개 일때 
# driver.switch_to_window(driver.window_handles[1])
# driver.close()

# 팝업창이 여러개 일때 
main = driver.window_handles
for handle in main:
    if handle != main[0]:
        driver.switch_to_window(handle)
        driver.close()

#'장난감' 코너 눌러보기
driver.switch_to_window(driver.window_handles[0])
driver.find_element_by_class_name('logo-toysrus').click()

참고 

https://bit.ly/3bpX6hy 

https://dejavuqa.tistory.com/110

https://www.youtube.com/watch?v=ItvnZHG_AJk

https://www.youtube.com/watch?v=sWTvgJhJ1oQ&t=328s

category IT/Python 2020. 5. 1. 09:10 by JeffreyOh

def close_handles(self, driver):
    global main_handle

    handles = driver.window_handles
    size = len(handles)

    main_handle = driver.current_window_handle
    for x in range(size):
    	if handles[x] != main_handle:
    		driver.switch_to.window(handles[x])
    		driver.close()

    driver.switch_to.window(main_handle)

    driver.switch_to.frame(0)

메인핸들만 제외한 나머지 창(새창, 팝업창 등등) 닫고 메인핸들로 스위칭 후 frame 첫번째까지 스위칭하는 소스

언어별 문법만 바꾸면 다 사용 가능