I'm trying to get my program (written in python) to open multiple links at the same time. I can open one link – but when I change my command from find_element_by_link_text to find_elements_by_link_text it doesn't work.
For context, I'm trying to open all links on the page with the name 'Annual Report'.
Here's the code I've tried:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import options
driver = webdriver.Chrome()
driver.get('https://webb-site.com/')
search = driver.find_element_by_name('code')
search.click()
search.send_keys("1830")
search.send_keys(Keys.RETURN)
element = driver.find_element_by_link_text('Financials')
element.click()
element = driver.find_elements_by_link_text('Annual Report')
element.click()
Here's my error
AttributeError: 'list' object has no attribute 'click'
As I said above. By removing the s in 'elements' it works fine but only opens the first 'Annual Report'.
You are getting AttributeError: 'list' object has no attribute 'click' error due to click on a list object. If you want to click multiple items then use a for loop.
driver = webdriver.Chrome()
driver.get('https://webb-site.com/')
search = driver.find_element_by_name('code')
search.click()
search.send_keys("1830")
search.send_keys(Keys.RETURN)
element = driver.find_element_by_link_text('Financials')
element.click()
element = driver.find_elements_by_link_text('Annual Report')
# print(element)
# print(len(element))
# element.click()
for c in element:
c.click()
You are calling click to a list object.
The object element in the last line:
element = driver.find_elements_by_link_text('Annual Report')
is a list.
When you call find_elements you get in return a list.
Just change it to:
element = driver.find_element_by_link_text('Annual Report')
Edit
As #Samsul added, to click on all the elements you'll need to loop through the list.
Related
I'm trying to get the text from the searched result but it shows me "TypeError: 'WebElement' object is not iterable" and want compare it with expected result below is my code [Python+Selenium]
from selenium import webdriver
import time texts = []
driver = webdriver.Chrome(executable_path = "C:\\chromedriver.exe")
driver.maximize_window() driver.get("https://rahulshettyacademy.com/seleniumPractise/#/")
driver.find_element_by_css_selector("input.search-keyword").send_keys("ber")
texts = driver.find_elements_by_xpath("//div[#class='product']/h4") print(texts)
Here is the website: https://rahulshettyacademy.com/seleniumPractise/#/
Trying to search "ber" and want to get all the product names
Thanks for your help in Advacne!
There are several issues here.
First of all you have to add a delay before getting the resulted elements with driver.find_elements_by_xpath("//div[#class='product']/h4")
The best way to do that is to introduce an Expected Conditions explicit wait.
Also your texts object is a list of web elements.
You can't print it directly.
What you can do is to iterate over that list of web elements and extract a text from each web element and then print it.
The following should work better:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time texts = []
driver = webdriver.Chrome(executable_path = "C:\\chromedriver.exe")
wait = WebDriverWait(driver, 20)
driver.maximize_window() driver.get("https://rahulshettyacademy.com/seleniumPractise/#/")
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input.search-keyword")))
driver.find_element_by_css_selector("input.search-keyword").send_keys("ber")
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[#class='product']/h4")))
text_elements = driver.find_elements_by_xpath("//div[#class='product']/h4")
for text_element in text_elements:
el_text = text_elements.text
print(el_text)
I am trying to use selenium to search for courses on https://catalog.swarthmore.edu/ and scrape the results. All the selectors I have attempted to use fail, and when I print them out they return empty arrays. Why did these selectors fail, and what is the correct one? I get the "#keyword" and "span input" from hovering over and clicking on the search field with the chrome SelectorGadget extension, and I obtained the "span.show.clearfix input" and ".show.clearfix input" from examining the HTML with Chrome Devtools.
#import scrapy
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import json
browserOptions = Options()
browserOptions.add_argument('--headless')
driver = webdriver.Chrome('C:/WebDriver/bin/chromedriver.exe', options=browserOptions)
def css(selector):
return driver.find_elements_by_id(selector)
driver.get("https://catalog.swarthmore.edu/")
print(driver.title)
search = css("span.show.clearfix input")#css("#keyword")#get search field
print(search)
print(css("span input"))
print(css(".show.clearfix input"))
print(css("#keyword"))
search.send_keys("ANCH 028")#enter your search.
search.submit()
search.clear()#clear search field
driver.quit()
Error message:
Traceback (most recent call last):
File "getDescWJSON.py", line 31, in
search.send_keys("ANCH 028")#enter your search.
AttributeError: 'list' object has no attribute 'send_keys'
The page has multiple elements with id=keyword so the results is a list. To send the keys, select the first element from the list:
Try this code:
search = css('keyword')[0] #("span.show.clearfix input")#css("#keyword")#get search field
You should probably change the name of the function css since it actually searches by element id.
You could simply do this to send the keys to that element. Wait for the element to come up after page load and send keys to the element.
search=WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//input[#id='keyword']"))).send_keys("ANCH 028")
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
This worked for me:-
driver.get('https://catalog.swarthmore.edu/')
btn = driver.find_element_by_xpath('''/html/body/table/tbody/tr[3]/td[1]/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td/form/fieldset/span[3]/input[1]''')
btn.click() #you have to click it first
btn.send_keys("ANCH 028")
I'm trying to close a modal with the 'x' button but I'm getting this error 'list' object has no attribute 'click' so I looked for other answers and they said to use close_button[0].click() since find_by_element stores a list but still getting error as IndexError: list index out of range
I need help to close this modal
my code
close_button=browser.find_elements_by_xpath('//*[#id="prefix-overlay-header"]/button')
close_button[0].click()
The element that I'm trying to access and close.
My 2c using Expected Conditions (waits):
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
wait = WebDriverWait(driver, 10)
driver.maximize_window()
driver.get('https://site.tld')
el = wait.until(EC.element_to_be_clickable((By.XPATH, '//button[text()="Close subscription dialog"]')))
el.click()
Based on your comment, you may want to use the following code after "click is executed" and which opens a new tab:
wait.until(EC.number_of_windows_to_be(2)) # wait for 2 tabs (windows) to be open
driver.switch_to_window(driver.window_handles[1]) # switch to newly opened tab
It is because your a trying to find the elements by
browser.find_elements_by path
Note that you can see elements. Elements is a list.It is plural
Try this:
browser.find_element_by_path
And then use closebutton.click()
I found the answer. As there is a space you should use css selector. The important things are the points(.)
close_button = browser.find_element_by_css_selector('.prefix-overlay-close.prefix-overlay-action-later')
close_button.click()
It worked for me in your given website. Please check once
I tried below 2 ways to wait before clicking button, but I am getting an error. I want to wait until anchor text stored query is available.
element = WebDriverWait(driver, 200).until(EC.presence_of_element_located((By.ANCHOR,"stored query")))
driver.find_element_by_link_text("[Comma-Delimited Text (CSV)]").click()
or:
wait.until(ExpectedConditions.textToBePresentInElement(By.xpath("path"), "stored query"));
driver.find_element_by_link_text("[Comma-Delimited Text (CSV)]").click()
Error:
wait.until(ExpectedConditions.textToBePresentInElement(By.xpath("path"), "stored query"));
AttributeError: 'module' object has no attribute 'until'
I just went thru web page again searching any element that has id and found one form.
My final code for just waiting page is:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.expected_conditions import presence_of_element_located
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC, wait
# Some code for loading web page
WebDriverWait(driver, 200).until(EC.presence_of_element_located((By.ID, "call_list")))
# Hit button/ perform next action
driver.find_element_by_link_text("[Comma-Delimited Text (CSV)]").click()
How do I use Python to simply find a link containing text/id/etc and then click that element?
My imports:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
Code to go to my URL:
browser = webdriver.Firefox() # Get local session of firefox
browser.get(myURL) # Load page
#right here I want to look for element containing "Click Me" in the text
#and then click it
Look at method list of WebDriver class - http://selenium.googlecode.com/svn/trunk/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html
For example, to find element by its ID and click it, the code will look like this
element = browser.find_element_by_id("your_element_id")
element.click()
Hi there are a couple of ways to find a link (or any element):
element = driver.find_element_by_id("element-id")
element = driver.find_element_by_name("element-name")
element = driver.find_element_by_xpath("//input[#id='element-id']")
element = driver.find_element_by_link_text("link-text")
element = driver.find_element_by_class_name("class-name")
I think the best option for you is find_element_by_link_text since it's a link.
Once you saved the element in a variable, you call the click function: element.click() or element.send_keys(Keys.RETURN)
Take a look to the selenium-python documentation, there are a couple of examples there.
You just use this code
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 time
driver = webdriver.Firefox()
driver.get("https://play.spotify.com/")# here change your link
wait=WebDriverWait(driver,250)
# it will wait for 250 seconds an element to come into view, you can change the #value
submit=wait.until(EC.presence_of_element_located((By.LINK_TEXT, 'Click Me')))
submit.click()
here wait is best fit for javascript enabled website let suppose if you load the page in webdriver but due to javascript some element loads after some second then it best suite to use wait element there.
for link containing text
browser = webdriver.firefox()
browser.find_element_by_link_text(link_text).click()
You can also do it by xpath:
Browser.find_element_by_xpath("//a[#href='you_link']").click()
Finding Element by Link Text
driver.find_element_by_link_text("")
Finding Element by Name
driver.find_element_by_name("")
Finding Element By ID
driver.find_element_by_id("")
Try SST - it is a simple yet very good test framework for python.
Install it first: http://testutils.org/sst/index.html
Then:
Imports:
from sst.actions import *
First define a variable - element - that you're after
element = assert_element(text="some words and more words")
I used this: http://testutils.org/sst/actions.html#assert-element
Then click that element:
click_element('element')
And that's it.
First start one instance of browser. Then you can use any of the following methods to get element or link. After locating the element you can use element.click() or element.send_keys(Keys.RETURN) or any other object of selenium webdriver
browser = webdriver.Firefox()
Selenium provides the following methods to locate elements in a page:
To find individual elements. These methods will return individual element.
browser.find_element_by_id(id)
browser.find_element_by_name(name)
browser.find_element_by_xpath(xpath)
browser.find_element_by_link_text(link_text)
browser.find_element_by_partial_link_text(partial_link_text)
browser.find_element_by_tag_name(tag_name)
browser.find_element_by_class_name(class_name)
browser.find_element_by_css_selector(css_selector)
To find multiple elements (these methods will return a list). Later you can iterate through the list or with elementlist[n] you can locate individual element from list.
browser.find_elements_by_name(name)
browser.find_elements_by_xpath(xpath)
browser.find_elements_by_link_text(link_text)
browser.find_elements_by_partial_link_text(partial_link_text)
browser.find_elements_by_tag_name(tag_name)
browser.find_elements_by_class_name(class_name)
browser.find_elements_by_css_selector(css_selector)
browser.find_element_by_xpath("")
browser.find_element_by_id("")
browser.find_element_by_name("")
browser.find_element_by_class_name("")
Inside the ("") you have to put the respective xpath, id, name, class_name, etc...