Python Selenium: Element currently not visible - python

I have this page. I have to click on Facebook icon. Upon doing it I m getting:
selenium.common.exceptions.ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
Code is given below:
if 'log' in html.lower():
print("not logged in")
sleep(3)
#Click on Fb button
fb_element = driver.find_element_by_xpath('//a[#tooltip="Facebook"]')
fb_element.vis
fb_element.send_keys(Keys.TAB)

There is an another element with tooltip="Facebook" on the page and this element is actually invisible. Well, there are actually 10 of them:
> $x('//a[#tooltip="Facebook"]').length
10
You can find find all elements matching your locator and filter the visible one via next() and is_displayed():
facebook_links = driver.find_elements_by_xpath('//a[#tooltip="Facebook"]')
visible_link = next(link for link in facebook_links if link.is_displayed())
visible_link.click()

Related

Python Selenium: Click Instagram next post button

I'm creating an Instagram bot but cannot figure out how to navigate to the next post.
Here is what I tried
#Attempt 1
next_button = driver.find_element_by_class_name('wpO6b ')
next_button.click()
#Attempt 2
_next = driver.find_element_by_class_name('coreSpriteRightPaginationArrow').click()
Neither of two worked and I get a NoSuchElementException or ElementClickInterceptedException . What corrections do I need to make here?
This is the button I'm trying to click(to get to the next post)
I have checked your class name coreSpriteRightPaginationArrow and i couldn't find any element with that exact class name. But I saw the class name partially. So it might help if you try with XPath contains as shown below.
//div[contains(#class,'coreSpriteRight')]
another xpath using class wpO6b. there are 10 elements with same class name so filtered using #aria-label='Next'
//button[#class='wpO6b ']//*[#aria-label='Next']
Try these and let me know if it works.
I have tried below code and it's clicking next button for 10 times
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
if __name__ == '__main__':
driver = webdriver.Chrome('/Users/yosuvaarulanthu/node_modules/chromedriver/lib/chromedriver/chromedriver') # Optional argument, if not specified will search path.
driver.maximize_window()
driver.implicitly_wait(15)
driver.get("https://www.instagram.com/instagram/");
time.sleep(2)
driver.find_element(By.XPATH,"//button[text()='Accept All']").click();
time.sleep(2)
#driver.find_element(By.XPATH,"//button[text()='Log in']").click();
driver.find_element(By.NAME,"username").send_keys('username')
driver.find_element(By.NAME,"password").send_keys('password')
driver.find_element(By.XPATH,"//div[text()='Log In']").click();
driver.find_element(By.XPATH,"//button[text()='Not now']").click();
driver.find_element(By.XPATH,"//button[text()='Not Now']").click();
#it open Instagram page and clicks 1st post and then it will click next post button for the specified range
driver.get("https://www.instagram.com/instagram/");
driver.find_element(By.XPATH,"//div[#class='v1Nh3 kIKUG _bz0w']").click();
for page in range(1,10):
driver.find_element(By.XPATH,"//button[#class='wpO6b ']//*[#aria-label='Next']" ).click();
time.sleep(2)
driver.quit()
As you can see, the next post right arrow button element locator is changing between the first post to other posts next page button.
In case of the first post you should use this locator:
//div[contains(#class,'coreSpriteRight')]
While for all the other posts you should use this locator
//a[contains(#class,'coreSpriteRight')]
The second element //a[contains(#class,'coreSpriteRight')] will also present on the first post page as well, however this element is not clickable there, it is enabled and can be clicked on non-first pages only.
As you can see on the picture below, the wp06b button is inside a lot of divs, in that case you might need to give Selenium that same path of divs to be able to access the button or give it a XPath.
It's not the most optimized but should work fine.
driver.find_element(By.XPATH("(.//*[normalize-space(text()) and normalize-space(.)='© 2022 Instagram from Meta'])[1]/following::*[name()='svg'][2]")).click()
Note that the XPath leads to a svg, so basically we are clicking on the svg element itself, not in the button.

Pop-up saying element not interactable Selenium

There are two pop-ups: One that asks if you live in California and the second one looks like this:
Here is my code:
The second pop-up doesn't show up every time and when it doesn't the function works. When it does I get an element not interactable error and I don't know why. Here is the inspector for the second pop-up close-btn.
test_data = ['Los Angeles','San Ramon']
base_url = "https://www.hunterdouglas.com/locator"
def pop_up_one(base_url):
driver.get(base_url)
try:
submit_btn = WebDriverWait(driver,5).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"[aria-label='No, I am not a California resident']")))
submit_btn.click()
time.sleep(5)
url = driver.current_url
submit_btn = WebDriverWait(driver,5).until(EC.presence_of_element_located((By.XPATH, "//*[contains(#class,'icon')]")))
print(submit_btn.text)
#submit_btn.click()
except Exception as t:
url = driver.current_url
print(t)
return url
else:
url = driver.current_url
print("second pop_up clicked")
return url
I have tried selecting by the aria-label, class_name, xpath, etc. the way I have it now shows that there is a selenium web element when I print just the element but it doesn't let me click it for some reason. Any direction appreciated. Thanks!
There are 41 elements on that page matching the //*[contains(#class,'icon')] XPath locator. At least the first element is not visible and not clickable, so when you trying to click this submit_btn element this gives element not interactable error.
In case this element is not always appearing you should use logic clicking element only in case the element appeared.
With the correct, unique locator you code can be something like this:
submit_btn = WebDriverWait(driver,5).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"[aria-label='No, I am not a California resident']")))
submit_btn.click()
time.sleep(5)
url = driver.current_url
submit_btn = driver.find_elements_by_xpath('button[aria-label="Close"]')
if(submit_btn):
submit_btn[0].click()
Here I'm using find_elements_by_xpath, this returns a list of web elements. In case element was not found it will be an empty list, it is interpreted as Boolean False in Python.
In case the element is found we will click on the first element in the returned list which will obviously the desired element.
UPD
See the correct locator used here.
It can also be in XPath syntax as //button[#aria-label="Close"]

How to loop clicks with Selenium using Python?

I am trying to loop clicks with Selenium,
the first click is working but the second gives error below:
selenium.common.exceptions.ElementNotInteractableException: Message: Element could not be scrolled into view
Here is the code:
def send_keys_dropdown(self,url):
bot = self.bot
bot.get(url)
elements = bot.find_elements_by_xpath("//a[#data-tag='globalize']")
for elem in elements:
class_of_element = elem.get_attribute("class")
if class_of_element == 'CsLinkButton':
elem.click()
time.sleep(5)
# close icon
bot.find_element_by_xpath("//a[#data-tag='cmdCancel']").click()
How I can click these elements inside loop? Thank you!
It seems after click action performed element may be inside scroll down or up window form.
following may help you please go through it.
after click action performed add following line.
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);",
elem);
here, "elem" is web element of your click button.

Get get_attribute("value") after refresh the page

Currently mu scenario is so:
send send_keys to a field
click in "save" button (refresh the page after click)
get get_attribute("value")after refresh the page
My code:
def fill_twitter(self):
enter_twitter = "http://" + fake.text(max_nb_chars=13) + ".com"
twitter_field = self.find_element(*ContractorsLocators.TWITTER)
twitter_field.send_keys(enter_twitter)
self.find_element(*ContractorsLocators.SAVE_BUTTON).click()
time.sleep(4)
assert twitter_field.get_attribute("value") == enter_twitter
My error:
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
How can I get the get_attribute("value")?
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
The most frequent cause of this is that page that the element was part of has been refreshed, or the user has navigated away to another page.
As you are saying page is getting refreshed when click on save button. Hence to avoid this you need to find same element (refresh element) again to getting their value as below :-
assert self.find_element(*ContractorsLocators.TWITTER).get_attribute("value") == enter_twitter
As the page got refreshed, you better save the value of the attribute before the element gets Stale.
def fill_twitter(self):
enter_twitter = "http://" + fake.text(max_nb_chars=13) + ".com"
twitter_field = self.find_element(*ContractorsLocators.TWITTER)
twitter_field.send_keys(enter_twitter)
value = twitter_field.get_attribute("value")
self.find_element(*ContractorsLocators.SAVE_BUTTON).click()
time.sleep(4)
assert value == enter_twitter
To check element is visible after page is refreshed use explicit sleep() function and after 4 seconds check that component is visible or not using WebDriverWait.
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"));
Visit http://selenium-python.readthedocs.io/waits.html#explicit-waits for better understanding.

Python & Selenium - unknown error: Element is not clickable at point (663, 469). Other element would receive the click:

I have this Selenium Code that should click on a size selection button.
submit_button = driver.find_element_by_class_name('pro_sku')
elementList = submit_button.find_elements_by_tag_name("a")
elementList[3].click()
It works for other pages but now on one page I get this error:
selenium.common.exceptions.WebDriverException: Message: unknown error: Element is not clickable at point (663, 469). Other element would receive the click:
I don't understand it because I can look at the browser window that Selenium opens and I normally can click on these buttons.
How can I solve this?
Someone asked for the website. Here it is: http://de.sinobiological.com/GM-CSF-CSF2-Protein-g-19491.html
You can use Xpath for element selection and then use the following method
# Click on Element
def element_click(self, xpath):
xpath = re.sub('"', "'", xpath)
browser.execute_script("""
var elements = document.evaluate("%s",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null);
var im = elements.snapshotItem(0);
im.click();
""" %(xpath)
)
So if your x-path is correct and item is present on DOM then definitely it will get clicked.
Happy Coding
You can use action_chains to simulate mouse movment
actions = ActionChains(driver)
actions.move_to_element(elementList[3]).perform()
elementList[3].click()
Edit
The <a> tags are not the actual sizes. Try
sizes = driver.find_elements_by_class_name('size_defaut')
sizes[3].click()
Try below:-
driver.execute_script("arguments[0].click();", elementList[3])
Hope it will help you :)

Categories