[PYTHON] Selenium WebDriver for Python이 페이지가로드 될 때까지 기다리십시오.
PYTHONSelenium WebDriver for Python이 페이지가로드 될 때까지 기다리십시오.
무한한 스크롤에 의해 구현 된 페이지의 모든 데이터를 긁어 내고 싶습니다. 다음 python 코드가 작동합니다.
for i in range(100):
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
즉, 아래로 스크롤 할 때마다 5 초 정도 기다려야합니다. 일반적으로 페이지에서 새로 생성 된 콘텐츠를로드하기에 충분합니다. 그러나 이것은 시간이 효율적이지 않을 수 있습니다. 페이지가 5 초 이내에 새 내용로드를 완료 할 수 있습니다. 아래로 스크롤 할 때마다 페이지가 새 내용로드를 완료했는지 어떻게 알 수 있습니까? 이 문제를 발견 할 수 있으면 페이지가로드되는 것을 알게되면 다시 스크롤하여 내용을 볼 수 있습니다. 이것은보다 효율적입니다.
해결법
-
==============================
1.webdriver는 기본적으로 .get () 메소드를 통해 페이지가로드 될 때까지 대기합니다.
webdriver는 기본적으로 .get () 메소드를 통해 페이지가로드 될 때까지 대기합니다.
@ user227215가 말한 것처럼 특정 요소를 찾고있을 수 있으므로 WebDriverWait을 사용하여 페이지에있는 요소를 기다려야합니다.
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.common.exceptions import TimeoutException browser = webdriver.Firefox() browser.get("url") delay = 3 # seconds try: myElem = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, 'IdOfMyElement'))) print "Page is ready!" except TimeoutException: print "Loading took too much time!"
나는 그것을 점검하는 데 사용했다. 다른 유형의 메소드를 사용하여 위치 지정자를 찾을 수 있습니다.
편집 1 :
나는 webdriver가 기본적으로 페이지가로드 될 때까지 기다릴 것이라고 언급해야한다. 프레임이나 Ajax 요청을로드 할 때까지 기다리지 않습니다. 이것은 .get ( 'url')을 사용할 때 브라우저가 페이지가 완전히로드 될 때까지 기다린 다음 코드의 다음 명령으로 이동한다는 의미입니다. 그러나 Ajax 요청을 게시 할 때 webdriver는 기다리지 않고 페이지 또는 페이지 일부가로드 될 때까지 적절한 시간 동안 기다리는 것은 사용자의 책임입니다. 따라서 expected_conditions라는 모듈이 있습니다.
-
==============================
2.presence_of_element_located에 대한 find_element_by_id를 생성자에 전달하려고하면 (허용 된 대답에 표시된대로) NoSuchElementException이 발생합니다. 나는 fragles의 주석에 구문을 사용해야 만했다.
presence_of_element_located에 대한 find_element_by_id를 생성자에 전달하려고하면 (허용 된 대답에 표시된대로) NoSuchElementException이 발생합니다. 나는 fragles의 주석에 구문을 사용해야 만했다.
from selenium import webdriver from selenium.common.exceptions import TimeoutException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By driver = webdriver.Firefox() driver.get('url') timeout = 5 try: element_present = EC.presence_of_element_located((By.ID, 'element_id')) WebDriverWait(driver, timeout).until(element_present) except TimeoutException: print "Timed out waiting for page to load"
이것은 문서의 예제와 일치합니다. 여기에 By의 설명서 링크가 있습니다.
-
==============================
3.아래 3 가지 방법을 찾으십시오.
아래 3 가지 방법을 찾으십시오.
확인 페이지 readyState (신뢰할 수 없음) :
def page_has_loaded(self): self.log.info("Checking if {} page is loaded.".format(self.driver.current_url)) page_state = self.driver.execute_script('return document.readyState;') return page_state == 'complete'
새 페이지 ID와 이전 페이지 ID 비교 :
def page_has_loaded_id(self): self.log.info("Checking if {} page is loaded.".format(self.driver.current_url)) try: new_page = browser.find_element_by_tag_name('html') return new_page.id != old_page.id except NoSuchElementException: return False
staleness_of 메소드 사용 :
@contextlib.contextmanager def wait_for_page_load(self, timeout=10): self.log.debug("Waiting for page to load at {}.".format(self.driver.current_url)) old_page = self.find_element_by_tag_name('html') yield WebDriverWait(self, timeout).until(staleness_of(old_page))
자세한 내용은 해리의 블로그를 확인하십시오.
-
==============================
4.selenium / webdriver / support / wait.py에서
selenium / webdriver / support / wait.py에서
driver = ... from selenium.webdriver.support.wait import WebDriverWait element = WebDriverWait(driver, 10).until( lambda x: x.find_element_by_id("someId"))
-
==============================
5.David Cullen의 답변에서 언급했듯이 다음과 같은 줄을 사용하는 것이 좋습니다.
David Cullen의 답변에서 언급했듯이 다음과 같은 줄을 사용하는 것이 좋습니다.
element_present = EC.presence_of_element_located((By.ID, 'element_id')) WebDriverWait(driver, timeout).until(element_present)
By 구문과 함께 사용할 수있는 가능한 모든 위치 지정자를 어디서든지 찾기가 어려웠으므로 여기에 목록을 제공하는 것이 유용 할 것이라고 생각했습니다. Ryan Mitchell의 Web Scraping with Python에 따르면 :
-
==============================
6.100 번 아래로 스크롤하는 대신 DOM에 더 이상 수정이 없는지 확인할 수 있습니다 (페이지의 맨 아래에 AJAX가 느리게로드되는 경우)
100 번 아래로 스크롤하는 대신 DOM에 더 이상 수정이 없는지 확인할 수 있습니다 (페이지의 맨 아래에 AJAX가 느리게로드되는 경우)
def scrollDown(driver, value): driver.execute_script("window.scrollBy(0,"+str(value)+")") # Scroll down the page def scrollDownAllTheWay(driver): old_page = driver.page_source while True: logging.debug("Scrolling loop") for i in range(2): scrollDown(driver, 500) time.sleep(2) new_page = driver.page_source if new_page != old_page: old_page = new_page else: break return True
-
==============================
7.어떻게 WebDriverWait을 While 루프에 넣고 예외를 잡는가?
어떻게 WebDriverWait을 While 루프에 넣고 예외를 잡는가?
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException browser = webdriver.Firefox() browser.get("url") delay = 3 # seconds while True: try: WebDriverWait(browser, delay).until(EC.presence_of_element_located(browser.find_element_by_id('IdOfMyElement'))) print "Page is ready!" break # it will break from the loop once the specific element will be present. except TimeoutException: print "Loading took too much time!-Try again"
-
==============================
8.당신은 driver.implicitly_wait을 시도해 보셨습니까? 그것은 드라이버의 설정과 같아서 세션에서 한 번만 호출하면 기본적으로 드라이버에게 각 명령을 실행할 수있을 때까지 주어진 시간 동안 대기하도록 지시합니다.
당신은 driver.implicitly_wait을 시도해 보셨습니까? 그것은 드라이버의 설정과 같아서 세션에서 한 번만 호출하면 기본적으로 드라이버에게 각 명령을 실행할 수있을 때까지 주어진 시간 동안 대기하도록 지시합니다.
driver = webdriver.Chrome() driver.implicitlyWait(10)
따라서 대기 시간을 10 초로 설정하면 가능한 한 빨리 명령을 실행하고 포기하기 10 초를 기다립니다. 비슷한 스크롤 - 다운 시나리오에서 이것을 사용했기 때문에 왜 당신의 경우에는 효과가 없을지 모르겠습니다. 희망이 도움이 :)
from https://stackoverflow.com/questions/26566799/wait-until-page-is-loaded-with-selenium-webdriver-for-python by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 문자열에서 팬더 DataFrame 만들기 (0) | 2018.10.02 |
---|---|
[PYTHON] Selenium : driver.quit ()를 호출하지 않고 geckodriver 프로세스가 PC 메모리에 영향을 미치지 않게하는 방법? (0) | 2018.10.02 |
[PYTHON] Pandas Series / DataFrame 전체를 멋지게 인쇄하십시오. (0) | 2018.10.02 |
[PYTHON] 하나의 키에 대해 다중 값을 사전에 추가 [duplicate] (0) | 2018.10.02 |
[PYTHON] 파일이 파이썬에 존재하는지 어떻게 확인합니까? (0) | 2018.10.02 |