16

So, what's I want to do is to run a function on a specific webpage (which is a match with my regex).

Right now I'm checking it every second and it works, but I'm sure that there is a better way (as it's flooding that website with getting requests).

while flag:
    time.sleep(1)
    print(driver.current_url)
    if driver.current_url == "mydesiredURL_by_Regex":
        time.sleep(1)
        myfunction()

I was thinking to do that somehow with WebDriverWait but not really sure how.

Ratmir Asanov
  • 6,237
  • 5
  • 26
  • 40
gyula
  • 247
  • 1
  • 3
  • 14
  • According to the [official documentation](https://seleniumhq.github.io/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.wait.html), this is almost exactly what using WebDriverWait does. It checks a condition by default every 0.5s. One advantage is that using a single line with WebDriverWait is more readable than the >5 lines it would take with any other method. – Mattwmaster58 Mar 22 '18 at 03:16

6 Answers6

18

This is how I implemented it eventually. Works well for me:

driver = webdriver.Chrome()
wait = WebDriverWait(driver, 5)
desired_url = "https://yourpageaddress"

def wait_for_correct_current_url(desired_url):
    wait.until(
        lambda driver: driver.current_url == desired_url)
Svetlana Levinsohn
  • 1,550
  • 3
  • 10
  • 19
  • 1
    This solution worked in my case. current_url = 'https://www.yourpageaddress.com/auth/login/' desired_url = 'https://www.yourpageaddress.com/' – Gh0sT Apr 12 '20 at 19:54
14

I was thinking to do that somehow with WebDriverWait

Exactly. First of all, see if the built-in Expected Conditions may solve that:

  • title_is
  • title_contains

Sample usage:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)
wait.until(EC.title_is("title"))
wait.until(EC.title_contains("part of title"))

If not, you can always create a custom Expected Condition to wait for url to match a desired regular expression.

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • got one more, a bit nooby question. is that timeout neccessary? I mean, maybe that script have to wait about 30 minutes for that expected condition/regex is there a good way to handle that too? thanks – gyula Mar 30 '16 at 18:49
  • @gyula from what I recall, the timeout is required..either set it to a large value, or use the "while true" approach.. – alecxe Mar 30 '16 at 18:59
6

To really know that the URL has changed, you need to know the old one. Using WebDriverWait the implementation in Java would be something like:

wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.not(ExpectedConditions.urlToBe(oldUrl)));

I know the question is for Python, but it's probably easy to translate.

Hatya
  • 71
  • 1
  • 1
  • 1
    Actually, in Python you can use EC.url_changes(url) which returns True as soon as driver.current_url is not equal to url (anymore). So no need to negate EC.url_to_be. – Robert Mar 16 '23 at 16:30
6

Here is an example using WebdriverWait with expected_conditions:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC 

url = 'https://example.com/before'
changed_url = 'https://example.com/after'

driver = webdriver.Chrome()
driver.get(url)

# wait up to 10 secs for the url to change or else `TimeOutException` is raised.
WebDriverWait(driver, 10).until(EC.url_changes(changed_url))
Corey Goldberg
  • 59,062
  • 28
  • 129
  • 143
  • For me it works with just waiting until the current URL changes, without needing to know the target URL: `WebDriverWait(driver, 10).until(EC.url_changes(driver.current_url))` – Primoz Jun 16 '23 at 11:35
1

Use url_matches Link to match a regex pattern with a url. It does re.search(pattern, url)

from selenium import webdriver
import re
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

pattern='https://www.example.com/'
driver = webdriver.Chrome()
wait = WebDriverWait(driver,10)

wait.until(EC.url_matches(pattern))
Aseem
  • 5,848
  • 7
  • 45
  • 69
1

I just used while loop

prev_url = str(driver.current_url)
driver.find_element(By.CSS_SELECTOR, '[data-cy="sidebar-game-over-new-game-button"]').click()
    while prev_url == str(driver.current_url):
        pass 
  • Please read [answer] and [edit] your answer to contain an explanation as to why this code would actually solve the problem at hand. Always remember that you're not only solving the problem, but are also educating the OP and any future readers of this post. – Adriaan Mar 22 '23 at 06:33