I'm trying to use Pythons Selenium module to click on an element whose link has the text "xlsx" at the end of it. Below is the code I'm using and the details of the element. Can someone please see why Python is unable to find this element?
driver.find_element_by_partial_link_text('xlsx').click()
Here is the element details:
<a name="URL$2" id="URL$2" ptlinktgt="pt_new" tabindex="43" onfocus="doFocus_win0(this,false,true);" href="http:******/HSC8_CNTRCT_ITEMS_IMPRVD-1479218.xlsx" onclick="window.open('http:********/HSC8_CNTRCT_ITEMS_IMPRVD-1479218.xlsx','','');cancelBubble(event);return false;" class="PSHYPERLINK">HSC8_CNTRCT_ITEMS_IMPRVD-1479218.xlsx</a>
I had to remove some parts of the URL for confidentiality purposes, however, it should not impact the answering of the question.
Thanks.
Thanks for the replies. Turns out, as #Andersson mentioned, the window was in a different frame.
I solved the problem using the following code before the find_element: driver.switch_to.frame('ptModFrame_0').
You can use a CSS selector:
driver.find_element_by_css_selector("a[href*='xlsx']")
If the element still cannot be located, I would suggest using a wait statement, to ensure that the element is visible, before you interact with it.
Please try:
driver.find_element_by_xpath(".//a[contains(#href,'xlsx')]").
You can grab it by class name (class name = PSHYPERLINK).
This should work:
import selenium
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
url = ''
driver = webdriver.Chrome('/path/to/chromedriver/executable')
if __name__=='__main__':
driver.get(url)
time.sleep(3)
driver.find_element_by_class_name('PSHYPERLINK').click()
When finding the attribute, make sure to use a singular '"element". Like:
driver.find_element_by_class_name('PSHYPERLINK').click()
not:
driver.find_elements_by_class_name('PSHYPERLINK').click()
Hope this helps.
Related
I'm very new and learning web scraping in python by trying to get the search results from the website below after a user types in some information, and then print the results. Everything works great up until the very last 2 lines of this script. When I include them in the script, nothing happens. However, when I remove them and then just try typing them into the shell after the script is done running, they work exactly as I'd intended. Can you think of a reason this is happening? As I'm a beginner I'm also super open if you see a much easier solution. All feedback is welcome. Thank you!
#Setup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
#Open Chrome
driver = webdriver.Chrome()
driver.get("https://myutilities.seattle.gov/eportal/#/accountlookup/calendar")
#Wait for site to load
time.sleep(10)
#Click on street address search box
elem = driver.find_element(By.ID, 'sa')
elem.click()
#Get input from the user
addr = input('Please enter part of your address and press enter to search.\n')
#Enter user input into search box
elem.send_keys(addr)
#Get search results
elem = driver.find_element(By.XPATH, ('/html/body/app-root/main/div/div/account-lookup/div/section/div[2]/div[2]/div/div/form/div/ul/li/div/div[1]'))
print(elem.text)
I haven't used Selenium in a while, so I can only point you in the right direction. It seems to me you need to iterate over the individual entries, and print those, as opposed to printing the entire div as one element.
You should remove the parentheses from the xpath expression
You can shorten the xpath expression as follows:
Code:
elems = driver.find_element(By.XPATH, '//*[#class="addressResults"]/div')
for elem in elems:
print(elem.text)
You are using an absolute XPATH, what you should be looking into are relative XPATHs
Something like this should do it:
elems = driver.find_elements(By.XPATH, ("//*[#id='addressResults']/div"))
for elem in elems:
...
I ended up figuring out my problem - I just needed to add in a bit that waits until the search results actually load before proceeding on with the script. tossing in a time.sleep(5) did the trick. Eventually I'll add a bit that checks that an element has loaded before proceeding with the script, but this lets me continue for now. Thanks everyone for your answers!
I'm trying to use Selenium to create a new message in my mailbox. I have a problem with finding napisz (en: 'write') button on my e-mail website. I tried to use driver.find_element_by_link_text but it doesn't work. I've managed to go workaround this problem using xpath but I'm very curious why the first method fails.
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Firefox()
browser.get('https://profil.wp.pl/login.html?zaloguj=poczta&url=https://poczta.wp.pl/profil/')
elem_login = browser.find_element_by_name('login_username')
elem_login.send_keys('stack_scraper_wp#wp.pl')
elem_password = browser.find_element_by_name('password')
elem_password.send_keys('thankyouforhelp')
elem_zaloguj_button = browser.find_element_by_id('btnSubmit')
elem_zaloguj_button.click()
browser.get('https://poczta.wp.pl/d635/indexgwt.html#start')
elem_napisz_button = browser.find_element_by_link_text('napisz')
elem_napisz_button.click()
EDIT: I've tried to used same xpath today but it failed. Is it possible that it's somehow dynamic causing the problem?
.find_element_by_link_text() looks for a elements only. In your case, this is the button element and cannot be located using this locator.
Go to google.com
Type a search keyword
I want to select 3rd/4th value from the auto suggestions list. What method should I use in selenium python ?
I don't know python, but i do have code in C# which i was able to succeed. You can give it try.
IWebDriver driver = new InternetExplorerDriver();
driver.Navigate().GoToUrl("https://www.google.com/");
IWebElement txtboxSearch = driver.FindElement(By.Id("lst-ib"));
txtboxSearch.SendKeys("ap");
IList<IWebElement> autosaerchList = driver.FindElements(By.CssSelector(".sbsb_c.gsfs"));
autosaerchList[1].Click();
Google search page contains a <div class="gstl_0 sbdd_a">
When you start typing into the search box, that div becomes populated with an <ul role="listbox">. The <li> in that list contain the 4 suggestions. Pick one, and call the .click() method.
from selenium import webdriver
import time
driver = webdriver.Chrome('Path to chromedriver\chromedriver.exe')
driver.get('http://google.com')
driver.maximize_window()
driver.find_element_by_name('q').send_keys('Shah') #pass whatever you want to search
time.sleep(5)
# to click on third element of search suggestion
driver.find_element_by_xpath('//div/div[3]/form/div[2]/div[2]/div[1]/div[2]/div[2]/div[1]/div/ul/li[3]/div/div[2]').click()
# to click on fourth element of search suggestion, uncomment the next line and comment the previous one
#driver.find_element_by_xpath('//div/div[3]/form/div[2]/div[2]/div[1]/div[2]/div[2]/div[1]/div/ul/li[4]/div/div[2]').click()
Hope this help
I have an element of type hidden in an iframe. I am wondering if there would be any way to get this value as I am using selenium. More specifically it is a captcha field. I've tried pulling it with something along the lines of
#!/usr/bin/env python
from selenium import webdriver
driver=webdriver.Chrome(chrome_bin_path)
driver.get('http://websitehere.com')
print driver.find_element_by_xpath('//*[#id="recaptcha-token"]').text
but because of it's hidden nature it returns nothing.
Below is a snippet of the source.
Highlighted is the string of interest. (value)
driver.switch_to_frame('undefined')
token_value = driver.find_element_by_id('recaptcha-token').get_attribute('value')
driver.switch_to_default_content()
Moving between windows and frames.
Use this method
hidden_text = element.get_attribute("textContent")
I am trying to get the Nasdaq "Most Advanced" list of stocks from here: http://www.nasdaq.com/extended-trading/premarket-mostactive.aspx (click on Most Advanced tab)
What is the best way using Selenium to loop through all the Symbols and put them into a Python list? I have figured out the XPATH to the first Symbol:
/html/body/div[4]/div[3]/div/div[7]/div[2]/table/tbody/tr[2]/td/div/h3/a
but am not sure where to go from there.. I tried:
element=driver.find_elements_by_xpath("/html/body/div[4]/div[3]/div/div[7]/div[2]/table/tbody/tr[2]/td/div/h3/a")
print element.text
..as a start just to see if I can get a value but it obviously doesn't work. Sorry for the stupid question :(
These xpaths containing the full absolute path to the element are very fragile.
Rely on the class name (//div[#class="symbol_links"]):
from selenium.webdriver.firefox import webdriver
driver = webdriver.WebDriver()
driver.get('http://www.nasdaq.com/extended-trading/premarket-mostactive.aspx')
# choose "Most Advanced" tab
advanced_link = driver.find_element_by_id('most-advanced')
advanced_link.click()
# get the symbols
print [symbol.text for symbol in driver.find_elements_by_xpath('//div[#class="symbol_links"]') if symbol.text]
driver.close()
prints:
[u'RNA', u'UBIC', u'GURE', u'DRTX', u'DSLV', u'YNDX', u'QIWI', u'NXPI', u'QGEN', u'ZGNX']
Hope that helps.