python Selenium options drop down - python

I am new to python. I have a code in R that I am trying to replace with a python
script. I am running into issues getting python to select a value from a drop
down menu.
This is the code in R that worked:
remDr$findElement(using = 'xpath', "//select[#id = 'groupby1']/option[#value = 'ReportDate']")$clickElement()
This is the HTML code:
select style="" class="dropdown" name="groupby1" id="groupby1" accesskey="" waffle_affected_fields=""
option value="ReportData">Report Date</option>
here are a couple things I tried after searching how to do this in python and I
keep running into errors.
find_element_by_xpath("//select[#id='groupby1']/option[#value='ReportDate']").click()
NameError: name 'find_element_by_xpath' is not defined
Select(driver.find_element_by_css_selector("select#groupby1")).select_by_value('ReportDate').click()
NameError: name 'Select' is not defined
Any help is appropriated!

Select doesn't have click(). Use it like this
Select(driver.find_element_by_id('groupby1')).select_by_value('ReportDate')
# or by text
Select(driver.find_element_by_id('groupby1')).select_by_visible_text('ReportDate')

These functions are properties of your webdriver instance. You need to do something like this:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.python.org")
driver.find_element_by_xpath("//select[#id='groupby1']/option[#value='ReportDate']").click()
See the getting started page for examples.

Related

Python Selenium variable not defined

I have a js file and i want to run it in a webpage. I am defining a lot of variable and function in this js file. I can run the code with execute_script(myScript) but when i do this, i can't use any variable or function in execute_script that defined in previous execute_script.
This is a test code:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.google.com")
driver.execute_script("let testVar = 10")
driver.execute_script("console.log(testVar)")
And this is the error:
selenium.common.exceptions.JavascriptException: Message: javascript
error: testVar is not defined
When declaring a variable with let test_var = 10 the variable will be defined in the script namespace and disappear when the script is finished.
If you want to keep the variable for use by another script, you have to anchor it to the document namespace. You can achieve that by defining an attribute on the document instance for example. If you are worried of namespace pollution, you can define a namespace for your scripts by adding an object attribute to document and storing your variables in this object.
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.google.com")
driver.execute_script("document.testVar = 10")
driver.execute_script("console.log(document.testVar)")

Import defined selenium function browser issue

Set-up
I use selenium for a variety of things and found myself defining the same functions over and over again.
I decided to define the functions in a separate file, and import these to my work files.
Simple Example
If I define functions and execute all in one file, things work fine. See the simple full_script.py below,
# import webdriver
from selenium import webdriver
# create browser
browser = webdriver.Firefox(
executable_path='/mypath/geckodriver')
# define short xpath function
def el_xp(x):
return browser.find_element_by_xpath(x)
# navigate to url
browser.get('https://nos.nl')
# obtain title first article
el_xp('/html/body/main/section[1]/div/ul/li[1]/a/div[2]/h3').text
This successfully returns the title of the first article on this news website.
Problem
Now, when I split the script in a xpath_function.py and a run_text.py, and save them in a test folder on my desktop, things don't work fine.
xpath_function.py
# import webdriver
from selenium import webdriver
# create browser
browser = webdriver.Firefox(
executable_path='/mypath/geckodriver')
# define short xpath function
def el_xp(x):
return browser.find_element_by_xpath(x)
run_test.py
import os
os.chdir('/my/Desktop/test')
import xpath_function as xf
# import webdriver
from selenium import webdriver
# create browser
browser = webdriver.Firefox(
executable_path='/Users/lucaspanjaard/Documents/RentIndicator/geckodriver')
browser.get('https://nos.nl')
xf.el_xp('/html/body/main/section[1]/div/ul/li[1]/a/div[2]/h3').text
Executing run_test.py results in 2 browsers opened, of which one navigates to the news website and the following error,
NoSuchElementException: Unable to locate element:
/html/body/main/section[1]/div/ul/li[1]/a/div[2]/h3
I suppose the issue is that in both xpath_function.py and run_test.py I'm defining a browser.
However, if I don't define a browser in xpath_function.py, I get an error in that file that no browser is defined.
How do I solve this?
You can easily fix it by changing the definition of el_exp to include the browser as an extra parameter:
def el_xp(browser, x):
return browser.find_element_by_xpath(x)
now in run_test.py you call it like this:
xf.el_xp(browser, '/html/body/main/section[1]/div/ul/li[1]/a/div[2]/h3').text

Python Selenium "WebDriverElement' object has no attribute 'get_attribute'

I am using Selenium and Splinter to run my UI tests for my web application. I am generating a random id for the views on the page and would like to select the random ID for testing.
Here is the code I am using
from selenium import webdriver
from splinter import Browser
executable_path = {'executable_path':'./chromedriver.exe'}
browser = Browser('chrome', **executable_path)
data_view_id = browser.find_by_xpath('//ul[#class="nav"]').find_by_xpath('.//a[#href="#"]')[0].get_attribute("data-view-id")
# I am trying to get the id for the first item in the nav list and use it elsewhere
print(data_view_id)
This is the error I am receiving:
AttributeError: 'WebDriverElement' object has no attribute 'get_attribute'
I've looked at the 'readthedocs' page for WebElement and it has the 'get_attribute' value. I cannot find any documentation regarding WebDriverElements and need help accessing the WebElement instead
That WebDriverElement is from Splinter, not Selenium.
In Splinter, you access attributes like a dict (see the Splinter docs)
data_view_id = browser.find_by_xpath('//ul[#class="nav"]').find_by_xpath('.//a[#href="#"]')[0]['data-view-id']
Or if you wanted to do it in Selenium:
browser.find_element_by_xpath('//ul[#class="nav"]').find_element_by_xpath('.//a[#href="#"]').get_attribute("data-view-id")

Test a string vs current_url in selenium

Using Python 3.4 and Selenium
I'm trying to test the current webpage vs a string. So for example:
while(webdriver.current_url == "https://www.youtube.com/"):
print("sleep")
time.sleep(5)
However, this does not work. I've tried printing out the links and just copying and pasting it to the string portion of my check, but that doesn't work either.
Any help is greatly appreciated.
My guess is that webdriver.current_url does not return a string, but I've encased it in str() in python and that still doesn't work. I've also tried making the current_url smaller, by doing current_url[1:-1] and so on, that hasn't helped so I'm not sure what other things I can try.
I tried with python 3.4, the code you shared is working for me.
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("https://www.youtube.com/")
time.sleep(5)
print(driver.current_url, type(driver.current_url), type("https://www.youtube.com/"))
while(driver.current_url == "https://www.youtube.com/"):
print("sleep")
time.sleep(5)
Add the following line for debugging purpose before while loop:
print webdriver.current_url, type(webdriver.current_url) # prints types as 'unicode' for me, but still code is working fine. tried with python 2.7
while(webdriver.current_url == "https://www.youtube.com/"):
print("sleep")
time.sleep(5)
Suggest to check what the value is being returned by webdriver.current_url
YouTube might be stripping the trailing / or adding query string parameters automatically after you navigate to the URL. Try:
while('https://www.youtube.com' in webdriver.current_url):
webdriver is the name of the python module you should have imported with: from selenium import webdriver. Therefore, it wouldn't even have a current_url property.
did you mean something like this?
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.youtube.com/')
if driver.current_url == "https://www.youtube.com/":
print('look, they are equal')
(notice I am getting the value of current_url from the webdriver.Chrome instance I create)

How to scrape dynamic content with Selenium?

I would like to scrape some interest rates. I need to use Selenium to access dynamically loaded content. For the Selenium part, the following works fine:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from scrapy.selector import Selector
chromedriver = "/usr/local/bin/chromedriver"
driver = webdriver.Chrome(chromedriver)
driver.get("http://www.infochoice.com.au/banking/savings-account/term-deposit-interest-rates.aspx")
driver.find_element_by_xpath("//select[#name='SavingsTerm']/option[text()='7 days']").click()
Now I would like to parse the html content to get the interest rates using something like:
xpath("//*[#id='IC_ProductList107Rate']/table/tbody/tr[5]/td/text()").extract()
It should be very easy, however I am new to Python and could not figure out a suitable procedure so far.
How can this be implemented?
I don't know if I understand very well but you can try with this:
driver.find_element_by_xpath("//*[#id='IC_ProductList107Rate']/table/tbody/tr[5]/td/text()").text
or
driver.find_element_by_xpath("//*[#id='IC_ProductList107Rate']/table/tbody/tr[5]/td/text()").get_attribute(element_attribute_value)
element_attribute_value can be 'value', 'text' etc... depend which attrbute you have in your HTML code

Categories

Resources