[selenium] python selenium timeout


linux 서버에서 python selenium 이용한 Crawling을 하면서 timoutexception 문제로 삽질했던 경험을 기록해 본다.

작업 환경

centos 3.7

python 3.6

selenium 3.141.0

chrome : 99.0.4844.51

Airflow : 1.10.x

  • Airflow Dag에서 selenium 을 사용하면서 발생한 문제였지만 Airflow 와는 관련이 없음을 확인했다. Airflow Dag이 아닌 Jupyter Lab, 일반 python(.py) 으로 동일한 코드로 테스트 시 동일 현상이 발견되었다.

현상

python selenium으로 Web crawling을 하는데 driver.get(url) 에서 TimeoutException 이 발생했다.

(timeout은 약 300초..)

문제는 아얘 안되는것이 아니고 10번하면 3~4번은 성공하고 나머지는 실패하는 식이었다.

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-gpu")

URL = '' #대상 URL
driver = webdriver.Chrome(executable_path='./chromedriver', chrome_options=options)
driver.get(url=URL)
#####> timeoutException 발생

원인1

구글링 결과 selenium이 headless 로 사용시 느리거나 Timeout이 발생할 수 있다는 포스팅을 발견했다.

조치방안1

구글링해서 ChromeOption 을 추가하면서 테스트 해보았다.

  • 추가 옵션

    –proxy-server=’direct://’

    –proxy-bypass-list=*

    ==> 결과 : 개선사항 없음 (TimeoutException 발생)

  • 추가옵션

    –dns-prefetch-disable

    –disable-dev-shm-usage

    –ignore-certificate-errors

    ==> 결과 : 개선사항 없음 (TimeoutException 발생)

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-gpu")

options.add_argument("--proxy-server='direct://'")
options.add_argument("--proxy-bypass-list=*")

options.add_argument("--dns-prefetch-disable")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--ignore-certificate-errors")

URL = '' #대상 URL
driver = webdriver.Chrome(executable_path='./chromedriver', chrome_options=options)
driver.get(url=URL)
#####> timeoutException 발생

**옵션 추가는 아무런 효과가 없었다!!**

원인 2

크롤링 대상 Web Site 의 문제일 수도 있다는 생각을 하게되었다.

원래 크롤링 하려는 URL 이 아닌 google.com 을 테스트해보았더니 timeoutException이 발생하지 않았다!!!

따라서 Web Site가 문제일 것이라는 합리적인 의심을 하게 되었다.

(Web site가 차단을 하는 것인지, 네트워크 구간상에 delay 가 발생한는 것인지는 정확히 파악하지 못했다)

근데 selenium headless 사용의 문제가 아닌 Web site 문제라면 해결방법이 없는것이 아닌가…

조치방안2

불규칙 적이지만 최소 5번에 한번은 성공하기 때문에 retry 횟수를 정하고 여러번 시도하여 한번은 성공하도록 로직을 구현했다.

성공하는경우는 driver.get() 이 몇초내로 완료되기 때문에 일정 시간내에 완료되지 않으면 retry 되도록 timeout 시간을 조정하도록 했다.

  • driver.set_page_load_timeout() : 정해진 시간내 페이지 로딩이 안되었을때 exception throw
from selenium import webdriver
import time

options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-gpu")

URL = '' #대상 URL
driver = webdriver.Chrome(executable_path='./chromedriver', chrome_options=options)
driver.set_page_load_timeout(10) # timeout 10 sec

crawling_success = False
for i in range(5):
    print(f'==try count:[{i+1}]')
    try:
        driver.get(url=URL)
        crawling_success = True
    except Exception as ex:
        print(f'==try count:[{i+1}] => exception:\n{ex}')
    if crawling_success == True:
        break
    time.sleep(5)
if crawling_success == False:
    raise AirflowException('retry gogo!') # Airflow Exception

...
#driver.find_element()

끝.




© 2021. by tytybro

Powered by tytybro