13

I've written a script that gets data from a page, but sometimes the page takes time to load and so when it pull the html into a soup object sometimes It pulls nothing as the page still needs to finish.

I wrote the following code for waiting the page to finish.

def scrape_page(url): browser.get(url) try: WebDriverWait(browser, 10).until(EC.presence_of_element_located(browser.find_element_by_id ("selection-box"))) #Extract Source Code html = browser.page_source; soup = BeautifulSoup(html) 

It works

But I'm getting the following error when I call the function;

TypeError: find_element() argument after * must be a sequence, not WebElement 

4 Answers 4

14

I think you should use presence_of_element_located like this:

element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) ) 

as described in the manual.

Sign up to request clarification or add additional context in comments.

5 Comments

I tried this originallly, , but get the error global name By is not defined. Only thing that is different is that Im using Chrome Driver instead of firefox
@GrantMcKinnonG import By before use it: from selenium.webdriver.common.by import By
@GrantMcKinnon- You have to import as from selenium.webdriver.common.by import By
The link in this answer has died. RIP link.
5

After 6 years from this question, all the solutions I looked for was not good for my situation, I found the solution in other programming language and I did implementation for Python, so this is the best way to wait a page to fully load.

WebDriverWait(self.driver, self.SERVER_TIMEOUT).until( lambda wd: self.driver.execute_script("return document.readyState") == 'complete', "Page taking too long to load" ) 

Comments

2

I apply this func to every WebElement I need to use.

from selenium import webdriver def FindElem(Driver: webdriver, XPath: str, Timeout: int = 300): while Timeout > 0: try: return Driver.find_element_by_xpath(XPath) except: # if element isn't already loaded or doesn't exist time.sleep(1) Timeout -= 1 raise RuntimeError(f"Page loading timeout") # or whatever the hell you want 

Usage:

Driver = webdriver.Firefox() webdriver.get("http://somewhere.com/somepage.html") MyWebElement = FindElem(Driver, "//input[@name='email']") # raise exception if timeout 

Comments

0

Load the class for the browser your using and use implicitly_wait. implicitly_wait will wait for whatever element your trying to find. This is built into selenium and works perfectly for finding WebElements on a page that hasn't finished loading.

from datetime import datetime from selenium.webdriver import Firefox from selenium.webdriver.common.by import By from selenium.common.exceptions import NoSuchElementException firefox = Firefox() firefox.implicitly_wait(time_to_wait = 120) # in seconds: 2 minutes firefox.get('https://www.google.com/') timestamp = datetime.now().timestamp() try: firefox.find_element(by = By.LINK_TEXT, value = 'aedgsf') except NoSuchElementException: pass time = datetime.fromtimestamp(datetime.now().timestamp() - timestamp).strftime('%M:%S:%f') print(time) 
>>> 02:00:910277 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.