I want a WebDriver instance to monitor a page indefinitely until an input box appears with the name 'move.' Once the input box appears, I want to fill it with some text and click a submit button adjacent to the form. What is the easiest way to do this?
I have something like this now:
try:
move = WebDriverWait(driver, 1000).until(
EC.presence_of_element_located((By.NAME, "move"))
)
finally:
wd.quit()
And the button adjacent to the form has no name or id, so I am locating it by XPATH. I want to wait until that form is present before click the button.
How do I do this?
monitor a page indefinitely until an input box appears
An Explicit wait you've used in the example requires a timeout value defined. Either you set a very high value for the timeout, or it is not an option.
Alternatively, you can have a while True loop until an element would be found:
from selenium.common.exceptions import NoSuchElementException
while True:
try:
form = driver.find_element_by_name("move")
break
except NoSuchElementException:
continue
button = form.find_element_by_xpath("following-sibling::button")
button.click()
where I'm assuming the button element is a following sibling of the form.
Related
I am getting trouble while shifting from the previous window to pop window and then pressing this press and hold button as we cannot able to get the id or class because it's dynamically changing. Is there any solution to get rid of this pop menu by long press and hold using selenium lib?
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//p[contains(.,'Press and Hold')]//preceding::input[1]")))
# element = driver.find_element_by_xpath("/html/body/div/div/div[2]/div[2]/p")
print("backing ot forward....")
action = ActionChains(driver)
action.click_and_hold(element)
action.perform()
time.sleep(10)
action.release(element)
action.perform()
time.sleep(0.2)
action.release(element)
```
Above are the lines of code that I am trying to run but due to dynamic id, it doesn't work well.
Here is something you may try. I had a similar issue. This worked for me.
The key is the release after 10 seconds (the timing might be different for your use case) and clicks again
element = driver.find_element_by_css_selector('#id-captcha') # captcha id
action = ActionChains(driver)
click = ActionChains(driver)
action.click_and_hold(element)
action.perform()
time.sleep(10) # change it as required
action.release(element)
action.perform()
time.sleep(0.2)
action.release(element)
I'm trying to automate MS Teams and can't get past the login because after entering the password I am having issues clicking the Sign In button.
If I try:
button = driver.find_element_by_xpath('//*[#id="idSIButton9"]')
button.click()
I get:
ElementNotInteractableException: Message: element not interactable.
If I try to solve it with Action Chains method (which seems to have solved many similiar issues for lots of people):
button = driver.find_element_by_xpath('//*[#id="idSIButton9"]')
driver.implicitly_wait(10)
ActionChains(driver).move_to_element(button).click(button).perform()
I get:
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
It is worth mentioning that when logging in manually I can get past this stage with pressing return after entering my password but I couldn't be successful with send keys methods neither.
If you still filled the form use submit() function - It is there to make your life easier.
Import webdriver:
from selenium import webdriver
Create webdriver object:
driver = webdriver.Firefox()
Get the website:
driver.get("https://www.YOUR_WEBSITE.de/")
Get element - In your case input for password
element = driver.find_element_by_xpath('//*[#id="i0118"]')
Send keys - Enter password
element.send_keys("YOUR_PASSWORD")
Submit contents
element.submit()
The element which you are trying to locate using the XPath driver.find_element_by_xpath('//*[#id="idSIButton9"]') might be the part of the previous screen and new screen, hence the driver might be referring to the element which is part of the previous screen, hence you are getting the StaleElementReferenceException.
The simplest way to resolve this is you can add, driver.refresh() just before the above xpath, this will load the page and DOM with the new elements.
Else, you can use a different locator strategy which will uniquely identify that element.
I have all of my options selected on this form and have the following code to click the Search button:
WebDriverWait(wd, 10).until(EC.element_to_be_clickable((By.ID, "alMatchFrequencies"))).click()
I have also tried this:
search = WebDriverWait(wd, 10).until(EC.element_to_be_clickable((By.ID, "alMatchFrequencies")))
search.send_keys(Keys.ENTER)
I have also tried subbing in RETURN instead of ENTER.
Here is a screenshot after that line is run:
The search bar is highlighted, but no results are being displayed. I can replicate this screen on my own and am able to press the search button so I don't think it is missing fields.
I believe you are actually clicking the search button but are not seeing the results because they are below the view you show. The scrollable area in your screenshot was a clue.
Clicking the search button is as easy as search.click() after you've executed the selector. But then you need to wait and scroll the page.
To Scroll a page you need to introduceActionChains in the Selenium library and to wait for the load you'll need to use Python's time.sleep(sec) function.
Full code to produce the attached picture:
#Imports
import time
from selenium.webdriver.common.action_chains import ActionChains
#...Code to Load and Select Filters...#
search = WebDriverWait(wd, 3000).until(EC.element_to_be_clickable((By.ID, "alMatchFrequencies")))
search.click()
# Wait for element to load
time.sleep(3)
# Locate element to scroll to
results = WebDriverWait(wd,3000).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[1]/section/div/div[2]/div/div[2]/div[5]/div/div[1]/div[5]")))
actions = ActionChains(wd)
# Scroll
actions.move_to_element(results).perform()
wd.get_screenshot_as_file("test3.png")
In one of my internal web applications, we have to select text in a webpage and click on the selection. then a popup opens up with more options. This is a repetitive task for me and I want to automate it but selecting a web element as we do manually is not working fine for me.
Since I cannot share the web app, I have taken a webpage accessible to all and tried to recreate the problem of selection.
I am trying to simulate manual selection using mouse click at the top left of the element, then pressing Shift, then again click at end of the element.
It's not working. What is wrong with the code?
Expected selection is attached as a picture:
Next is my code:
import selenium
import time
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
print("program has started")
# Customary code starts
myDriver=selenium.webdriver.Chrome("D:\\Software\\ChromeDriver\\chromedriver.exe")
myDriver.set_page_load_timeout(60)
myDriver.maximize_window()
myDriver.implicitly_wait(30)
# Customary code ends
# opening website
myDriver.get("https://en.wikipedia.org/wiki/Animal")
time.sleep(4)
actions = ActionChains(myDriver)
element=myDriver.find_element_by_xpath("//*[#id='mw-content-text']/div/p[2]")
actions.move_to_element(element)
myDriver.switch_to_active_element()
time.sleep(5)
actions.move_by_offset(-(element.size["width"])/2, -(element.size["height"])/2)
actions.click()
ActionChains(myDriver).key_down(Keys.SHIFT)
actions.move_by_offset((element.size["width"]),(element.size["height"]))
actions.click()
# actions.context_click()
actions.perform()
# print(element.size["width"])
# print(element.size["height"])
# print(element.location["x"])
# print(element.location["y"])
# print(element.location)
print("end of action")
print("Sucessfully came to the end")
#myDriver.quit()
# calling a action method as A
a=A(self.driver)
# Click on text box and enter some text
self.driver.find_element_by_xpath("/html/body/div[3]/div[3]/div/div/div/div/div[1]/main/div/form/div[1]/div[2]/div/div/div/div[1]/section/div[1]/div/div/div/div[2]/div/div/div/div/div/div").send_keys("amar")
time.sleep(2)
# performing control action
a.key_down(K.CONTROL).send_keys("a").perform()
time.sleep(2)
# selecting the text
a.key_down(K.CONTROL).send_keys("c").perform()
time.sleep(5)
#click on bold and appl
self.driver.find_element_by_xpath("/html/body/div[3]/div[3]/div/div/div/div/div[1]/main/div/form/div[1]/div[2]/div/div/div/div[1]/section/div[1]/div/div/div/div[1]/div[1]/div[1]").click()
time.sleep(5)
I would like to write a code that would make Python scrape some data on a page, then click on the "next" button at the bottom of the page, scrape some data on the second page, click on the "next" button, etc. until the last page, where clicking on "Next" is no longer possible (because there is no "next").
I would like to make the code as general as possible and not specify beforehand the number of clicks to be done.
Following this question (How can I make Selenium click through a variable number of "next" buttons?), I have the code below. Python does not report any error, but the program stops after the first iteration (after the first click on the "next").
What am I missing here? Many thanks!
driver = webdriver.Firefox()
driver.get("http://www.mywebsite_example.com")
try:
wait = WebDriverWait(driver, 100)
wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'reviews_pagination_link_nav')))
driver.find_element_by_class_name("reviews_pagination_link_nav").click()
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'reviews_pagination_link_nav')))
while EC.element_to_be_clickable((By.CLASS_NAME,'reviews_pagination_link_nav')):
driver.find_element_by_class_name("reviews_pagination_link_nav").click()
if not driver.find_element_by_class_name("reviews_pagination_link_nav"):
break
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'reviews_pagination_link_nav')))
finally:
driver.quit()
I would make an endless while True loop and break it once there is TimeoutException thrown - this would mean there are no pages to go left:
wait = WebDriverWait(driver, 10)
while True:
# grab the data
# click next link
try:
element = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'reviews_pagination_link_nav')))
element.click()
except TimeoutException:
break
For this to work, you need to make sure that once you hit the last page, the element with class="reviews_pagination_link_nav" is not on the page or is not clickable.