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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.