tag switch_to select_by_value page name for expected execute_script conditions python selenium execute-script

switch_to - Espere hasta que la página se cargue con Selenium WebDriver para Python



wait for selenium python (9)

¿Has probado driver.implicitly_wait ? Es como una configuración para el controlador, por lo que solo se llama una vez en la sesión y básicamente le dice al controlador que espere la cantidad de tiempo dada hasta que se pueda ejecutar cada comando.

driver = webdriver.Chrome() driver.implicitly_Wait(10)

Entonces, si establece un tiempo de espera de 10 segundos, ejecutará el comando lo antes posible, esperando 10 segundos antes de que se dé por vencido. He usado esto en escenarios similares de desplazamiento hacia abajo, así que no veo por qué no funcionaría en su caso. Espero que esto sea útil.

Quiero raspar todos los datos de una página implementada por un desplazamiento infinito. El siguiente código de Python funciona.

for i in range(100): driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(5)

Esto significa que cada vez que me desplazo hacia abajo, necesito esperar 5 segundos, lo que generalmente es suficiente para que la página termine de cargar los contenidos recién generados. Pero, esto puede no ser eficiente en el tiempo. La página puede terminar de cargar los nuevos contenidos en 5 segundos. ¿Cómo puedo detectar si la página terminó de cargar los nuevos contenidos cada vez que me desplazo hacia abajo? Si puedo detectar esto, puedo desplazarme hacia abajo nuevamente para ver más contenido una vez que sepa que la página terminó de cargarse. Esto es más eficiente en el tiempo.


¿Qué hay de poner WebDriverWait en el ciclo While y capturar las excepciones?

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"


Aquí lo hice usando una forma bastante simple:

from selenium import webdriver browser = webdriver.Firefox() browser.get("url") searchTxt='''' while not searchTxt: try: searchTxt=browser.find_element_by_name(''NAME OF ELEMENT'') searchTxt.send_keys("USERNAME") except:continue


Como se menciona en la respuesta de David Cullen , siempre he recomendado usar una línea como la siguiente:

element_present = EC.presence_of_element_located((By.ID, ''element_id'')) WebDriverWait(driver, timeout).until(element_present)

Fue difícil para mí encontrar en cualquier lugar todos los localizadores posibles que se puedan usar con la sintaxis By , por lo que pensé que sería útil proporcionar aquí la lista. Según Web Scraping with Python por Ryan Mitchell:

ID

Usado en el ejemplo; encuentra elementos por su atributo de identificación HTML

CLASS_NAME

Se usa para buscar elementos por su atributo de clase HTML. ¿Por qué esta función CLASS_NAME no es simplemente CLASS ? Usar el formulario object.CLASS crearía problemas para la biblioteca Java de Selenium, donde .class es un método reservado. Para mantener la sintaxis de Selenium consistente entre diferentes idiomas, se usó CLASS_NAME su lugar.

CSS_SELECTOR

Encuentre elementos por su clase, id o nombre de etiqueta, usando la #idName , .className , tagName .

LINK_TEXT

Encuentra etiquetas HTML por el texto que contienen. Por ejemplo, un enlace que dice "Siguiente" se puede seleccionar usando (By.LINK_TEXT, "Next") .

PARTIAL_LINK_TEXT

Similar a LINK_TEXT , pero coincide en una cadena parcial.

NAME

Encuentra etiquetas HTML por su atributo de nombre. Esto es útil para formularios HTML.

TAG_NAME

Ajusta las etiquetas HTML por su nombre de etiqueta.

XPATH

Utiliza una expresión XPath ... para seleccionar elementos coincidentes.


Desde 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"))


El webdriver esperará a que se cargue una página de forma predeterminada mediante el método .get() .

Como puede estar buscando algún elemento específico como dijo @ user227215, debe usar WebDriverWait para esperar un elemento ubicado en su página:

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!"

Lo he usado para verificar alertas. Puede usar cualquier otro tipo de método para encontrar el localizador.

EDITAR 1:

Debo mencionar que el webdriver esperará a que se cargue una página de forma predeterminada. No espera la carga dentro de los marcos o las solicitudes de ajax. Significa que cuando usa .get(''url'') , su navegador esperará hasta que la página esté completamente cargada y luego vaya al siguiente comando en el código. Pero cuando publica una solicitud ajax, webdriver no espera y es su responsabilidad esperar un tiempo apropiado para que se cargue la página o una parte de la página; Por lo tanto, hay un módulo llamado expected_conditions .


En una nota al margen, en lugar de desplazarse hacia abajo 100 veces, puede verificar si no hay más modificaciones en el DOM (en el caso de que la parte inferior de la página esté cargada de manera lenta 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


Encuentra a continuación 3 métodos:

readyState

Página de comprobación readyState (no confiable):

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''

La función wait_for helper es buena, pero desafortunadamente click_through_to_new_page está abierta a la condición de carrera en la que logramos ejecutar el script en la página anterior, antes de que el navegador haya comenzado a procesar el clic, y page_has_loaded simplemente vuelve a ser cierto de inmediato.

id

Comparando nuevos identificadores de página con el anterior:

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

Es posible que comparar identificadores no sea tan efectivo como esperar excepciones de referencia obsoletas.

staleness_of

Usando el método 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))

Para más detalles, consulte el blog de Harry .


Intentar pasar find_element_by_id al constructor para presence_of_element_located (como se muestra en la respuesta aceptada ) provocó que se NoSuchElementException . Tuve que usar la sintaxis en el comment los 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"

Esto coincide con el documentation . Aquí hay un enlace a la documentación de By .