How to edit chromes search and homepage with selenium/python? - python

I am trying to edit chrome browsers search and homepage using selenium/python. After navigating to chrome://settings/searchEngines and targeting the 'add' button with the ID 'addSearchEngine', I get an error when I run a .click function. How do I target this element correctly, or is there another way to update chromes search/startpage with python?
I'm guessing this element is trapped inside an iframe but I'm unable to find one on the page using the dev tools, xpath noted the following about the absolute xpath: "It might be a child of iframe from different src & it is not supported currently."
from selenium import webdriver
driver = webdriver.Chrome()
driver.set_page_load_timeout(10)
driver.get("chrome://settings/searchEngines")
driver.find_element_by_id("addSearchEngine").click()
Traceback (most recent call last):
File "C:/Users/Jonathan/PycharmProjects/test_project/test_project/Main.py", line 20, in <module>
driver.find_element_by_id("addSearchEngine").click()
File "C:\Python37-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "C:\Python37-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
'value': value})['value']
File "C:\Python37-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Python37-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="addSearchEngine"]"}
(Session info: chrome=75.0.3770.142)

chrome://settings/searchEngines has Shadow DOM elements . You will need to use the driver.execute_script() to get handle of the shadowRoot element and ultimately get to the 'addSearchEngine' element.
Example python : shadowRoot python
Example Java : For chrome://downloads/ shadowRoot java

Refer to this post for detailed explanation.
In your case you can do the below.
url = "chrome://settings/searchEngines"
driver.get(url)
addButton = driver.execute_script("return document.querySelector('settings-ui')"
".shadowRoot.querySelector('#main')"
".shadowRoot.querySelector('settings-basic-page.showing-subpage')"
".shadowRoot.querySelector('settings-search-page')"
".shadowRoot.querySelector('settings-search-engines-page')"
".shadowRoot.querySelector('#addSearchEngine')")
addButton.click()
Screenshot:

Related

Python Selenium - No Such Element Found... I'm Lost

I am trying to click on an element that should send me to the next page, however, I can't seem to properly locate it or even locate any item on the page.
HTML Code for Element
<a data-qa="menu-button"
class="HeaderMenu__HeaderItemButton-kr6p0e-0 hbeYmr MenuButton__MenuButtonWrapper-dq0g44-0 imLDTG"
data-cv-test="headerSearchLink"
href="/cars"
target="_self">Search Cars
</a>
Visual of what I'm trying to click on
My code that does not work (I have the proper import statements)
PATH = "my_path_to_chromedriver"
driver = webdriver.Chrome(PATH)
driver.get("https://www.carvana.com")
link = driver.find_element_by_class_name('HeaderMenu__HeaderItemButton-kr6p0e-0 hbeYmr MenuButton__MenuButtonWrapper-dq0g44-0 imLDTG')
link.click()
I have tried searching by class name using this approach and just get this error message
link = driver.find_element_by_class_name('HeaderMenu__HeaderItemButton-kr6p0e-0 hbeYmr MenuButton__MenuButtonWrapper-dq0g44-0 imLDTG')
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 564, in find_element_by_class_name
return self.find_element(by=By.CLASS_NAME, value=name)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".HeaderMenu__HeaderItemButton-kr6p0e-0 hbeYmr MenuButton__MenuButtonWrapper-dq0g44-0 imLDTG"}
(Session info: chrome=xx.x.xxxx.xxx)
I have also tried searching by CSS selector. I even did a little sanity check and searched for the very first line of html code on the website and for some reason it gave me the same error. Anything helps... thank you!
The problem is you have spaces in the class name. The class name function doesn't work for that, I would suggest trying
driver.find_element_by_css_selector('.HeaderMenu__HeaderItemButton-kr6p0e-0.hbeYmr.MenuButton__MenuButtonWrapper-dq0g44-0.imLDTG')
driver.find_element_by_class_name('HeaderMenu__HeaderItemButton-kr6p0e-0
hbeYmr MenuButton__MenuButtonWrapper-dq0g44-0 imLDTG')
This code give return a node list and u can't click it , you may try get the first element , so here is the code :
driver.find_element_by_class_name('HeaderMenu__HeaderItemButton-kr6p0e-0
hbeYmr MenuButton__MenuButtonWrapper-dq0g44-0 imLDTG')[0]
Or bye doing this in the console of the navigator with js like this :
document.getElementByNames('HeaderMenu__HeaderItemButton-kr6p0e-0
hbeYmr MenuButton__MenuButtonWrapper-dq0g44-0 imLDTG')[0]

Selenium Testing unable to target element

I am running some testing on our website using selenium.
At the login page I would like to target the login button and click it.
the source code of the page looks like this:
I am trying to target the second button that has the class=OTSigninButton by using its xpath.
so here is the python code.
time.sleep(5)
element = driver.find_element_by_xpath('//*[#id="root"]/div/div[1]/div/svg[2]/path')
element.click()
but when I run the code I get the following error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="root"]/div/div[1]/div/svg[2]/path"}
(Session info: chrome=91.0.4472.106)
Here is the weird part. The login page has 2 buttons, their xpath is similar as its a list.
the first button is:
//*[#id="root"]/div/div[1]/div/svg[1]/path
and the second button(the one I want to target) is
//*[#id="root"]/div/div[1]/div/svg[1]/path
As both of them has the id=root, if I find_element_by_id and target root, I am able to click on the first button.
Here is where I am struggling a lot, how can I use the xpath to target the second button?
thank you so much for your time and help guys.
EDIT: Full error
Traceback (most recent call last):
File "test.py", line 17, in <module>
element = driver.find_element_by_xpath("//*[local-name()='svg' and contains(#class, 'OTSigninButton')]/title")
File "/Users/<user>/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 394, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "/Users/<user>/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "/Users/<user>/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/Users/<user>/opt/anaconda3/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[local-name()='svg' and contains(#class, 'OTSigninButton')]/title"}
(Session info: chrome=91.0.4472.106)
class=OTSigninButton
is a attribute of SVG. These are special tags, you can not just write their tag name in console and locate them.
try this instead :
//*[local-name()='svg' and contains(#class, 'OTSigninButton')]

Python Selenium cannot find an element on a page by xpath

I am using python and selenium to test some things with fantasy football. Here is my code so far (I just started).
import time
from selenium import webdriver
driver = webdriver.Chrome('C:\\Users\\202300Fontenot\\Desktop\\3\\chromedriver.exe')
driver.get('http://games.espn.com/ffl/signin?redir=http%3A%2F%2Fgames.espn.com%2Fffl%2Fclubhouse%3FseasonId%3D2018%26leagueId%3D49607%26teamId%3D4');
driver.implicitly_wait(10)
time.sleep(10)
search_box = driver.find_element_by_xpath('//*[#id="did-ui-view"]/div/section/section/form/section/div[1]/div/label/span[2]/input')
search_box.send_keys('email#icloud.com')
search_box.submit()
time.sleep(5)
driver.quit()
This just tries to enter an email address into the box. I am getting this error every time:
Traceback (most recent call last):
File "C:\Users\202300Fontenot\Desktop\3\ESPN.py", line 8, in <module>
search_box = driver.find_element_by_xpath('//*[#id="did-ui-view"]/div/section/section/form/section/div[1]/div/label/span[2]/input')
File "C:\Users\202300Fontenot\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 393, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "C:\Users\202300Fontenot\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 966, in find_element
'value': value})['value']
File "C:\Users\202300Fontenot\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 320, in execute
self.error_handler.check_response(response)
File "C:\Users\202300Fontenot\AppData\Local\Programs\Python\Python36\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="did-ui-view"]/div/section/section/form/section/div[1]/div/label/span[2]/input"}
(Session info: chrome=69.0.3497.92)
(Driver info: chromedriver=2.42.591088 (7b2b2dca23cca0862f674758c9a3933e685c27d5),platform=Windows NT 10.0.16299 x86_64)
Thanks for your help.
Your problem is that the input you are trying to select exists inside of an iframe. You must first tell the driver to switch to the iframe and then execute the xpath selection.
driver.switch_to.frame("disneyid-iframe")
driver.find_element_by_xpath("//input[#type='email']").send_keys('email#icloud.com')
First of all you need to switch to your iframe using its name:
disneyid-iframe
Also if XPATH is not the only choice, you may use the CSS Selector:
div.field-username-email input[type='email']
This will get the driver to find & fill your field.
Using XPath in python You need to provide the string for
driver.find_element_by_xpath
Example Code below
("//*[#id=\"did-ui-view\"]/div/section/section/form/section/div[1]/div/label/span[2]/input")
Please refer below document regarding String
String Gude first Para

Locating element with python selenium using href in xpath

I have an issue locating element in Python Selenium using href within XPath. I have checked that my XPath is correct using Chrome console and I am happy with the result it returns.
I used the following to validate XPath on Chrome Console:
$x("//li[#id='result_0']//a[#href='https://www.amazon.co.uk/HuntGold-Plastic-Outdoor-Carrier-Container/dp/B00R7DCPWO/ref=sr_1_1?ie=UTF8&qid=1476540708&sr=8-1&keywords=banana+holder#customerReviews']")
Then I used the same XPath in my Python Selenium code:
path = "//li[#id='result_0]//a[#href='https://www.amazon.co.uk/HuntGold-Plastic-Outdoor-Carrier-Container/dp/B00R7DCPWO/ref=sr_1_1?ie=UTF8&qid=1476540708&sr=8-1&keywords=banana+holder#customerReviews']"
reviews = driver.find_element_by_xpath(path).text
and I got the following error message:
reviews = driver.find_element_by_xpath(reviews_path).text
File "/Users/Paulius/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 293, in find_element_by_xpath
return self.find_element(by=By.XPATH, value=xpath)
File "/Users/Paulius/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 752, in find_element
'value': value})['value']
File "/Users/Paulius/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 236, in execute
self.error_handler.check_response(response)
File "/Users/Paulius/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 192, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element
(Session info: chrome=53.0.2785.143)
(Driver info: chromedriver=2.16.333243 (0bfa1d3575fc1044244f21ddb82bf870944ef961),platform=Mac OS X 10.12.0 x86_64)
Does anyone know how to get href XPath in Python Selenium working?

Selenium cannot get iframe

I am trying to retrieve the Job Description and Job Requirements from this link:
https://www.jobsbank.gov.sg/ICMSPortal/portlets/JobBankHandler/SearchDetail.do?id=JOB-2016-0008238
using selenium. This is my code:
driver = webdriver.Firefox()
url = "https://www.jobsbank.gov.sg/ICMSPortal/portlets/JobBankHandler/SearchDetail.do?id=JOB-2016-0008238"
driver.get(url)
iframes = driver.find_elements_by_xpath('//*[#id="divMainJobDescription"]')
print len(iframes)
driver.switch_to_frame(iframes)
print driver.page_source
I get the following error:
Traceback (most recent call last): File "D:\scraper.py", line 79, in
main() File "D:\Abigail MTI Projects\Singapore Skills\JobsBankScraper\jobsbank14012016_abi.py", line 74, in main
driver.switch_to_frame(iframes) File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 537, in switch_to_frame
self._switch_to.frame(frame_reference) File "C:\Python27\lib\site-packages\selenium\webdriver\remote\switch_to.py",
line 67, in frame
self._driver.execute(Command.SWITCH_TO_FRAME, {'id': frame_reference}) File
"C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 201, in execute
self.error_handler.check_response(response) File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py",
line 181, in check_response
raise exception_class(message, screen, stacktrace) NoSuchFrameException: Message: Unable to locate frame: [object Object]
Stacktrace:
at FirefoxDriver.prototype.switchToFrame (file:///c:/users/mti_wl~1/appdata/local/temp/tmpwelh3x/extensions/fxdriver#googlecode.com/components/driver-component.js:10745)
at DelayedCommand.prototype.executeInternal_/h (file:///c:/users/mti_wl~1/appdata/local/temp/tmpwelh3x/extensions/fxdriver#googlecode.com/components/command-processor.js:12551)
at DelayedCommand.prototype.executeInternal_ (file:///c:/users/mti_wl~1/appdata/local/temp/tmpwelh3x/extensions/fxdriver#googlecode.com/components/command-processor.js:12556)
at DelayedCommand.prototype.execute/< (file:///c:/users/mti_wl~1/appdata/local/temp/tmpwelh3x/extensions/fxdriver#googlecode.com/components/command-processor.js:12498)
iframes is list, you need to switch to a single frame.
driver.find_elements return list while driver.find_element return single web element (note the 's' in element/s).
In addition, divMainJobDescription is not iframe, I believe you are looking for frameJobDescription
iframe = driver.find_element_by_id("frameJobDescription")
You need to target the iframe, switch to that frame, and then you can start identifying other elements, like divs, which exist inside that frame. You need to specify the iframe tag itself and not an element inside the iframe.
So, instead of targeting a div immediately inside the frame like
iframes = driver.find_elements_by_xpath('//*[#id="divMainJobDescription"]')
target the iframe tag, then switch. (You can use the singular find_element_by_xpath if you want only one iframe.)
iframe = driver.find_element_by_xpath('//iframe[#id="frameJobDescription"]')
driver.switch_to_frame(iframe)
job_description = driver.find_element_by_xpath('//*[#id="divMainJobDescription"]')
Bonus: You can use other methods to target the iframe, such as finding the element by ID instead of writing the xpath, if you are only looking at IDs.
iframe = driver.find_element_by_id('frameJobDescription')
If you need to get details in BOTH iframes during your script, you will need to take turns switching between frames.

Categories

Resources