No se puede obtener un contenido generado dinámicamente de una página web

He escrito un script en python usando selenium para obtener el business summary (que está dentro de la etiqueta p ) ubicado en la esquina inferior derecha de una página web bajo el encabezado Company profile . La página web es muy dinámica, por lo que pensé usar un simulador de navegador. He creado un selector css, que puede analizar el resumen si copio los html elements directamente desde esa página web y lo pruebo localmente. Por alguna razón, cuando probé el mismo selector en mi siguiente script, no funciona. Se timeout exception error de timeout exception lugar. ¿Cómo puedo ir a buscarlo?

Este es mi bash:

 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 from selenium.common.exceptions import TimeoutException link = "https://in.finance.yahoo.com/quote/AAPL?p=AAPL" def get_information(driver, url): driver.get(url) item = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "[id$='-QuoteModule'] p[class^='businessSummary']"))) driver.execute_script("arguments[0].scrollIntoView();", item) print(item.text) if __name__ == "__main__": driver = webdriver.Chrome() wait = WebDriverWait(driver, 20) try: get_information(driver,link) finally: driver.quit() 

Parece que inicialmente no hay un bloque de Resumen empresarial, pero se genera después de que se desplaza hacia abajo en la página. Intente a continuación la solución:

 from selenium.webdriver.common.keys import Keys def get_information(driver, url): driver.get(url) driver.find_element_by_tag_name("body").send_keys(Keys.END) item = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "[id$='-QuoteModule'] p[class^='businessSummary']"))) print(item.text) 

Tienes que desplazar la página hacia abajo dos veces hasta que el elemento esté presente:

 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 from selenium.common.exceptions import TimeoutException import time link = "https://in.finance.yahoo.com/quote/AAPL?p=AAPL" def get_information(driver, url): driver.get(url) driver.find_element_by_tag_name("body").send_keys(Keys.END) # scroll page time.sleep(1) # small pause between driver.find_element_by_tag_name("body").send_keys(Keys.END) # one more time item = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "[id$='-QuoteModule'] p[class^='businessSummary']"))) driver.execute_script("arguments[0].scrollIntoView();", item) print(item.text) if __name__ == "__main__": driver = webdriver.Chrome() wait = WebDriverWait(driver, 20) try: get_information(driver,link) finally: driver.quit() 

Si solo se desplazará una vez, no funcionará correctamente por algún motivo (al menos para mí). Creo que depende de las dimensiones de la ventana, en la ventana más pequeña tiene que desplazarse más que en una más grande.

Este es un enfoque mucho más simple utilizando solicitudes y trabajando con los datos JSON que ya se encuentran en la página. También recomendaría utilizar siempre la solicitud si es posible. Puede requerir un poco de trabajo adicional, pero el resultado final es mucho más confiable / más limpio. También podría tomar mi ejemplo mucho más y analizar JSON para que trabaje directamente con él (debe limpiar el texto para que sea JSON válido). En mi ejemplo, solo uso split, que fue más rápido de hacer, pero podría llevar a problemas en el camino cuando hago algo más complejo.

 import requests from lxml import html url = 'https://in.finance.yahoo.com/quote/AAPL?p=AAPL' headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} r = requests.get(url, headers=headers) tree = html.fromstring(r.text) data= [e.text_content() for e in tree.iter('script') if 'root.App.main = ' in e.text_content()][0] data = data.split('longBusinessSummary":"')[1] data = data.split('","city')[0] print (data)