I am trying to locate an href containing the substring '.ics', such as in the screenshot, and return the link as a string.
Below is my code attempt:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get('http://miamioh.edu/emss/offices/career-services/events/index.html')
element = driver.find_element_by_partial_link_text('.ics')
However, I get this error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"partial link text","selector":".ics"}
No doubt I am overlooking something very basic, but I can't figure out what. I have also tried the line
element = driver.findElement(By.cssSelector("a[href*='services.ics']")).click();
instead of the other line beginning with 'element'. However, this gives
AttributeError: 'WebDriver' object has no attribute 'findElement'
The link text is exact text of the link you see on web page while partial link text is just some substring of that link text.
"services.ics" is part of href attribute. If you want to find element by "services.ics" you might use
driver.find_element_by_xpath('//a[contains(#href, "services.ics")]')
Also you might use title attribute to match required element:
driver.find_element_by_xpath('//a[#title="iCal Feed"]')
Note that
element = driver.findElement(By.cssSelector("a[href*='services.ics']")).click();
is Java analogue of Python code
from selenium.webdriver.common.by import By
element = driver.find_element(By.CSS_SELECTOR, "a[href*='services.ics']").click();
Update
Link might be generated dynamically, so you can try to apply ExplicitWait as below to avoid NoSuchElementException:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as wait
wait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[#title="iCal Feed"]'))).click()
Update 2
As target link located inside an iframe you should switch to that frame before clicking link:
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it("trumba.spud.1.iframe"))
driver.find_element_by_xpath('//a[#title="iCal Feed"]').click()
In Python the Selenium method is driver.find_element. Also partial link text does not refer to the link, instead it refers to the text in the "a" tag. i.e.
this is the link text
Since you want to search for a <a href="..."> that ends with .ics. We can do this with a CSS selector, like:
a[href$=".ics"]
So we can use the following code:
element = driver.find_element_by_css_selector('a[href$=".ics"]')
Or if you are looking for 'services.ics':
element = driver.find_element_by_css_selector('a[href$="services.ics"]')
You need to get the attribute href. First locate that element without looking for the "HREF", then get the attribute.
myHrefVal = element.get_attribute('href')
print(myHrefVal)
As #Andersson has stated, try using the xPath.
driver.find_element_by_xpath('//a[#title="iCal Feed"]')
Good luck! :)
Related
I am trying to automate the process of liking pages on Facebook. I've got a list of each page's link and I want to open and like them one by one.
I think the Like button doesn't have any id or name, but it is in a span class.
<span class="x1lliihq x6ikm8r x10wlt62 x1n2onr6 xlyipyv xuxw1ft">Like</span>
I used this code to find and click on the "Like" button.
def likePages(links, driver):
for link in links:
driver.get(link)
time.sleep(3)
driver.find_element(By.LINK_TEXT, 'Like').click()
And I get the following error when I run the function:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element
The classname attribute values like x1lliihq, x6ikm8r, etc, are dynamically generated and is bound to chage sooner/later. They may change next time you access the application afresh or even while next application startup. So can't be used in locators.
Moreover the the element is a <span> tag so you can't use By.LINK_TEXT
Solution
To click on the element Like you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using XPATH and text():
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Like']"))).click()
Using XPATH and contains():
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//*[contains(., 'Like')]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
References
You can find a couple of relevant detailed discussions on NoSuchElementException in:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element
You cannot use Link_Text locator as Like is not a hyperlink. Use XPath instead, see below:
XPath : //span[contains(text(),"Like")]
driver.find_element(By.XPATH, '//span[contains(text(),"Like")]').click()
I'm trying to locate a tab and click it on my webpage. However, my code does not work:
ActionChains(driver).move_to_element(driver.find_element_by_xpath("//*[#id='tab_bd3ae39d-f956-49ab-b7bd-f13507de9351']/div[2]/div")).perform()
additionaldata_ele= driver.find_element_by_xpath("//*[#id='tab_bd3ae39d-f956-49ab-b7bd-f13507de9351']/div[2]/div").click()
The HTML body is as follows:
<li class="WJX1 WLV1" id="tab_015ba30c-af6c-4c9a-ac34-f77ee00805b6" role="tab" aria-controls="tabPanel_16845ddd-961b-4581-89da-a6a4e6080930" data-automation-id="tab" aria-selected="false"><div class="WGX1"></div><div class="WEX1"><div class="gwt-Label WLX1" data-automation-id="tabLabel">Additional Data</div></div></li>
I get the error -
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id='tab_bd3ae39d-f956-49ab-b7bd-f13507de9351']/div[2]/div"}
I guess the reason is that when I try to find the element, it doesn't appear on the DOM, so I should implement WebDriverWait until the element is visible. So I tried WebDriverWait, but it didn't work either.
Many thanks for all answers and replies!
second edition:
Here is the webpage, sorry I cannot share the link, it is an internal webpage and PSW is required:
This is the screenshot of the page
That id looks dynamic - it will probably change frequently and result in an unstable script.
Additionally, you will want a wait to ensure your web page is ready before you continue.
try something like this:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[text()="Additional Data"]'))).click()
Dear Stackoverflowers,
I'm trying to automate a CC payment process but Selenium is having a hard time identifying a specific element I want to click on. I'm trying to click on 'REI Card - 6137' so that I can continue to the payment page. Using the inspect tool it shows the class as, "soloLink accountNamesize". Unfortunately, there's not an ID I can go after. When I try to search by class name I get this error in the console:
selenium.common.exceptions.NoSuchElementException: Message: Unable to
locate element: .soloLink accountNamesize
Below is a picture of the site and the inspector pane with the thing I'm trying to click on highlighted in blue. Since its my credit card and I'm already logged it a link to the page wouldn't really help you guys.
The script gets hung up on "driver.find_element_by_class_name('soloLink accountNamesize').click()"
My code is below:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import yaml
import time
conf = yaml.load(open(r'D:\Users\Matt\Documents\GitHub\YML_Files\REI_Login_Credentials.yml'))
myREIUsername = conf['REILogin']['username']
myREIPassword = conf['REILogin']['password']
driver = webdriver.Firefox(
executable_path=
r'D:\Users\Matt\Documents\GitHub\Executable_Files\geckodriver.exe'
)
def login():
driver.get('https://onlinebanking.usbank.com/Auth/Login?usertype=REIMC&redirect=login&lang=en&exp=')
time.sleep(4)
driver.find_element_by_id('aw-personal-id').send_keys(myREIUsername)
driver.find_element_by_id('aw-password').send_keys(myREIPassword)
time.sleep(2)
driver.find_element_by_id('aw-log-in').click()
time.sleep(15)
make_payment()
def make_payment():
if (driver.find_element_by_class_name("accountRowLast").text) != "0.00":
driver.find_element_by_class_name('soloLink accountNamesize').click()
else:
driver.quit()
I've tried searching by Xpath and Xpath + Class with no luck. I also tried searching for this issue but its a fairly unique class so I didn't have much luck. Have any other ideas I could try?
soloLink accountNamesize is multiple class names use the following css selector instead to click on that element.
driver.find_element_by_css_selector('a.soloLink.accountNamesize').click()
To induce waits we do
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.soloLink.accountNamesize"))).click()
Based on the photo, I think that this is the xpath that you might want
//div[#id='MyAccountsDiv']//div[#id='CreditsTableDiv']//tbody//tr[#class='accountRowFirst']//a[contains(#onclick, 'OpenAccountDashboard')]
As you can see, this xpath starts off with the top-most div that might be unique ( MyAccountsDiv ) and continues to dive into the HTML code.
Based off of this, you could click on the link with the following code
xpath = "//div[#id='MyAccountsDiv']//div[#id='CreditsTableDiv']//tbody//tr[#class='accountRowFirst']//a[contains(#onclick, 'OpenAccountDashboard')]"
driver.find_element(By.XPATH, xpath).click()
NOTE
Your error says
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="aw-personal-id"]
Maybe you can use the above technique and see if you can isolate the xpath for the web element instead.
I am writing an automation script for sports betting in Python using Selenium. I am stuck at a point where Selenium is unable to click or send keys to the specific HTML element highlighted in the following screenshot (https://i.stack.imgur.com/NbljY.png).
Here is what I have tried:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.bet365.com")
### Some code here to navigate to a particular match
driver.switch_to.frame(bet_driver.find_element_by_tag_name("iframe"))
elem = driver.find_element_by_class_name("bs-Stake")
elem.click()
elem.send_keys("100")
This returns the following error:
ElementNotInteractableException: Element <div class="bs-Stake"> is not reachable by keyboard
If I try instead
elem = driver.find_element_by_class_name("stk bs-Stake_TextBox")
I get the error:
NoSuchElementException: Unable to locate element: .stk bs-Stake_TextBox
I would appreciate help navigating to the HTML element, clicking and sending keys to it, using any method available in Selenium.
Try to sendkeys with webdriver wait so element would be able to interact.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 50).until(EC.visibility_of_element_located((CSS_SELECTOR, ".stk.bs-Stake_TextBox")))
element.send_keys("100")
Although CSS styles are inherited... the class designations are not. Your css selector has three separate classes in it, but your element sample only has one.
Selenium is designed to mimic the same actions that a person can perform... the error suggests that the field is not available for interaction.... find out why.
I'm very new to Selenium.
I'm crawling data from this page. I need to scroll down the page and click on "Load More Arguments" to get more text. This is the location to click on.
<a class="debate-more-btn" href="javascript:void(0);" onclick="loadMoreArguments('15F7E61D-89B8-443A-A21C-13FD5EAA6087');">
Load More Arguments
</a>
I have tried this code but it does not work. Should I need more code to locate to that (I think the 1 has already tell the location to click). Do you have any recommendation? Thank you in advance.
[1] btn_moreDebate = driver.find_elements_by_class_name("debate-more-btn")
[2] btn.click()
Find the link by link text, move to the element and click:
from selenium.webdriver.common.action_chains import ActionChains
link = driver.find_element_by_link_text('Load More Arguments')
ActionChains(browser).move_to_element(link).perform()
link.click()
If you get an exception while finding an element, you may need to use an Explicit Wait:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
link = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, "Load More Arguments")))
ActionChains(browser).move_to_element(link).perform()
link.click()
If I understand your code correctly, I can see a few things wrong.
1. You're using find_elements_by_class_name. I'd recommend using find_element_by_class_name instead. elements returns a list, which isn't needed in a case where there is only one element.
2. You're using btn_moreDebate as the holder for the results of your find_elements, but then interacting with btn.
You should be able to perform the find and click in one action:
driver.find_element_by_class_name("debate-more-btn").click()