There's this element which manually I click so I can fill out the form and generate a file for download.
As I said, manually it's a clickable element that works just by clicking it. Here's the problem:
Clicking-in the element won't work, selenium is giving me the type of error saying the element is not iterable, I've tried also tried changing the 'class' attribute, which by what I saw, is what changes in the Html when I click it with Chrome prompt opened.
This is the HTML without clicking it(second image):
This is the Html when I click it(third image):
edit 14/01/2022 09_54:
The code i tried was:
element = ''
while element == '':
try:
element = nvg.find_element_by_xpath('/html/body/div[2]/div[1]/div[2]/div[2]/form/div[1]/label[2]')
except:
element = ''
"""so after this loop it is actually able to find and referenciate the element"""
nvg.find_element_by_xpath('/html/body/div[2]/div[1]'
'/div[2]/div[2]/form/div[1]/label[1]').__setattr__('class', "fancy_radio inline fancy_unchecked")
print(element.get_attribute('class'))
"""it prints the 'fancy_radio inline fancy_checked' string"""
element.__setattr__('class', "fancy_radio inline fancy_checked")
"""returns and changes nothing"""
element.click()
"""raises the not iterable element"""
Related
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.
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"]
I am trying to create a twitch follower bot, and have created simple code to go to the website and press the follow button, but it is not clicking the follow button.
import webbrowser
url = "https://twitch.tv/owlcrogs"
driver = webbrowser.open(url)
follow_button =
driver.find_element_by_xpath(get_page_element("follow_button"))
follow_button.click()
Where is defined get_page_element("follow_button")?
You must be sure It returns a valide xpath.
From Google Chrome you can inspect xpath with right click over the target element and select inspect. Then the developers tools are deployed. Over the selected item in the developers tools do [ right click >> copy >> copy Xpath ]
E.g.
driver.find_element_by_xpath('//*[#id="id_element"]/div[2]/a/span').click()
If if doesn't something is wrong with get_page_element. What is the type of error returned?
I have just checked the webPage and maybe you must put 'follow-button' instead of 'follow_button' with an hyphen instead of an underscore. However, I hope get_page_element search by data-a-target attribute, xD.
Here is a example to do that:
def find_element_by_attribute(wrapper, attribute, selection=None, xpath = None):
if selection is not None:
element = list(filter(lambda x: x.get_attribute(attribute) is not None and \
x.get_attribute(attribute).find(selection) != -1,\
wrapper.find_elements_by_xpath('.//*' if xpath is None else xpath)))
else:
element = list(filter(lambda x: x.get_attribute(attribute) is not None,\
wrapper.find_elements_by_xpath('.//*' if xpath is None else xpath)))
return None if len(element) is 0 else element[0]
wrapper : Page elements where search the target element (e.g. a div with li tags).
attribute : Attribute used to select the target element.
selecction : String with text which is in target attribute.
xpath : Could be used to search in a subwrapper element.
You could save this code un a module e.g. auxiliars.py
So your code after defining this function should be something like this:
import webbrowser
from auxiliars import find_element_by_attribute
url = "https://twitch.tv/owlcrogs"
driver = webbrowser.open(url)
follow_button = find_element_by_attribute(driver, 'data-a-target', selection='follow-button')
follow_button.click()
I have been wondering how I could see when I am at the last page on an amazon listing. I have tried to get at the last page number on the bottom of the screen with nothing working, so I tried a different approach. To see if the 'Next' button can still be clicked. Here is what i have so far, any ideas on why it wont go to the next page?
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium import webdriver
import time
def next():
giveawayPage = 1
currentPageURL = 'https://www.amazon.com/ga/giveaways?pageId=' + str(giveawayPage)
while True:
try:
nextButton = driver.find_element_by_xpath('//*[#id="giveawayListingPagination"]/ul/li[7]')
except:
nextPageStatus = 'false'
print('false')
else:
nextpageStatus = 'true'
giveawayPage = giveawayPage + 1
driver.get(currentPageURL)
if (nextPageStatus == 'false'):
break
if __name__ == '__main__':
driver = webdriver.Chrome('./chromedriver')
driver.get('https://www.amazon.com/ga/giveaways?pageId=1')
next()
The reason this doesn't work is because if you go to the last page of an Amazon Giveaway, the element that you're selecting is still there, it's just not clickable. On most pages, the element looks like:
<li class="a-last">...</li>
On the last page, it looks instead like:
<li class="a-disabled a-last">...</li>
So rather than checking if the element exists, it might be better to check if the element has the class 'a-disabled'.
the li for Next button is always exist, there are several ways to check if it last page:
check if the li has multiple class or not only a-last but also has class a-disabled
//li[#class="a-last"]
check if the <a> element exist in the li
//*[#id="giveawayListingPagination"]/ul/li[7]/a
Using python, selenium, and firefox. I am clicking a link on a homepage and it leads directly to a JPG file that loads. I just want to verify that the image loads. The HTML of the image is this:
<img src="https://www.treasury.gov/about/organizational-structure/ig/Agency%20Documents/Organizational%20Chart.jpg" alt="https://www.treasury.gov/about/organizational-structure/ig/Agency%20Documents/Organizational%20Chart.jpg">
I am trying to use xpath for locating the element:
def wait_for_element_visibility(self, waitTime, locatorMode, Locator):
element = None
if locatorMode == LocatorMode.XPATH:
element = WebDriverWait(self.driver, waitTime).\
until(EC.visibility_of_element_located((By.XPATH, Locator)))
else:
raise Exception("Unsupported locator strategy.")
return element
Using this dictionary:
OrganizationalChartPageMap = dict(OrganizationalChartPictureXpath = "//img[contains(#src, 'Chart.jpg')]",
)
This is the code I am running:
def _verify_page(self):
try:
self.wait_for_element_visibility(20,
"xpath",
OrganizationalChartPageMap['OrganizationalChartPictureXpath']
)
except:
raise IncorrectPageException
I get the incorrectpageexception thrown every time. Am I doing this all wrong? Is there a better way to verify images using selenium?
Edit : Here is the DOM of the elements :
Appending the alt value should work in xpath, would suggest you to change the dictionary to :
= dict(OrganizationalChartPictureXpath = "//img[#alt='https://www.treasury.gov/about/organizational-structure/ig/Agency%20Documents/Organizational%20Chart.jpg' and contains(#src, 'Chart.jpg')]"
OR
alternatively use the full path to the image in the src as :
= dict(OrganizationalChartPictureXpath = "//img[#src='https://www.treasury.gov/about/organizational-structure/ig/Agency%20Documents/Organizational%20Chart.jpg']"
Edit :
According to the DOM shared in the image, you can also use the class of the img which would be a corresponding code into your project to this :
element = driver.find_element_by_class_name('shrinkToFit')