how to find element selenium - python

How do I find
element = driver.find_element_by_id("id","class","class")
Im trying to click an ad
doing direct with xpath will not work:
/html/body/div/div[1]/div[1]/div/a/img
Traceback (most recent call last):
File "a.py", line 14, in <module>
element = driver.find_element_by_id("/html/body/div/div[1]/div[1]/div/a/img")
HTML shown as follows:
</head>
<body scroll="no">
<div id="widget" class="widget">
<div class="plug">
<div class="thumbBorder">
<div class="thumb">
<div class="ton" style="display: block;">
<div class="title_bg"> </div>
<a class="title q" target="_blank" href="//prwidgets.com/t/ghxa/g0us/7433c239e19107a4301ad9959d2d37440/aHR0cDovL3Ry‌​aXBsZXh2aWQuY29tLw==">Kiss N Tell</a>
</div>
<a class="q" target="_blank" href="//prwidgets.com/t/ghxa/g0us/7433c239e19107a4301ad9959d2d37440/aHR0cDovL3Ry‌​aXBsZXh2aWQuY29tLw=="> <img title="Title" src="//prstatics.com/prplugs/0/747604/160x120.jpg"

find_element_by_id in Selenium python binding accepts one parameter which is the value of the id attribute. Such as
login_form = driver.find_element_by_id('loginForm')
Please refer to the doc here
Addition to that you can use
driver.find_element(By.ID, 'your ID')

In this case you can try xpath- and axis i.e. following-sibling
element = driver.find_element_by_xpath("//a[class='q']/following-sibling::img[1]")
element.click()
N.B I have assumed there is no a with class name q in the whole html doument.

This may not work for you but when there is not an easy ID or NAME to grab, I go into the browser (I will refer to Firefox) right click on the element, select 'Inspect Element', then right click on the highlighted area in the inspection window and select 'Copy Unique Selector'. Then you can paste this into your code and use:
selector = 'pasted string here'
element = driver.find_element_by_css_selector(selector)
element.click()
EDIT: using the selector provided by #James below:
selector = 'div.plug:nth-child(1) > div:nth-child(1) > div:nth-child(1) > a:nth-child(2) > img:nth-child(1)'
element = driver.find_element_by_css_selector(selector)
element.click()
This usually works quite well for me.
EDIT: Add a real example. Try this and see if it works.
# open google search page and click the "About" link
from selenium import webdriver
driver = webdriver.Firefox()
driver.maximize_window()
driver.get('www.google.com/ncr')
# got the selector below using Firefox 'Inspect Element -> Copy Unique Selector'
about_selector = 'a._Gs:nth-child(3)'
about = driver.find_element_by_css_selector(about_selector)
about.click()

Related

Selenium cannot find element by name or id (Python)

I am trying to automate logging into a website using selenium, but I am getting "no such element message" error. Here is my code, with the link to the website included:
from selenium import webdriver
import time
import datetime
driver = webdriver.Chrome("C:\\Users\\Family\\Downloads\\chromedriver_win32\\chromedriver.exe")
driver.get("https://login.microsoftonline.com/c4d72b4d-8155-4a90-9155-7705148c41ca/saml2?SAMLRequest=jdE9a8MwEAbgvdD%2fYLRbkh3ZVoQdCO0SSJek7dClnJVzYrClVCeX%2fvw6DaEdu90HLzzc1espntwOPyakmGweG0YwDuHav3eqqFSHOZRQKZAZdJDpDjToKisXiCx5xUC9dw3LuWTJhmjCjaMILs4jmWepVKnMnrPCyNIscq601pVUbyxZE2GIc%2fbBO5pGDHsMn73Fl922YacYz2SEiAdqOQ4IwfXu6F2E0HtuQRzyQQxnAbNeDP7YO3Fxby8Vn3cs%2bRoHRw2bgjMeqCfjYEQy0Zr9%2bmlrZq45Bx%2b99QNb3d8lSf2DD%2f8Jwo3OVjdokdlSVrZKUS10quTSphrLIi00drrVebksWh7RzYch3ob%2beIp0Bovc%2bvGXXosrYgbV4u9nVt8%3d&RelayState=%2fd2l%2fhome&sso_reload=true")
login_button = driver.find_element_by_id("i0116")
login_button.send_keys("sajjad.jessa#student.tdsb.on.ca")
And here is the element I am trying to access with my code:
<input type="email" name="loginfmt" id="i0116" maxlength="113" lang="en" class="form-control ltr_override input ext-input text-box ext-text-box" aria-required="true" data-bind="
externalCss: {
'input': true,
'text-box': true,
'has-error': usernameTextbox.error },
ariaLabel: tenantBranding.UserIdLabel || str['CT_PWD_STR_Username_AriaLabel'],
ariaDescribedBy: 'loginHeader' + (pageDescription && !svr.fHideLoginDesc ? ' loginDescription' : ''),
textInput: usernameTextbox.value,
hasFocusEx: usernameTextbox.focused,
placeholder: $placeholderText" aria-label="Enter your TDSB email address here, then click Next" aria-describedby="loginHeader" placeholder="Enter your TDSB email address here, then click Next">
From other answers I understand that you have to use driver.find_element_by_css_selector() and driver.switch_to.frame(), but if you look at the full hypertext of the website, the first frame to go into is a "div" tag without any attributes. It is however the only "div" tag alongside two "script" tags. I need the correct code to go into the frame, or another method to automate logging in.
It seems synchronization Issue.
Induce WebDriverWait() and wait for element_to_be_clickable()
login_button =WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.ID,"i0116")))
login_button.send_keys("sajjad.jessa#student.tdsb.on.ca")
You need to import following libraries.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
login_button =WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.NAME,"loginfmt")))
The most of the large websites now uses dynamic layout. You should look for the parents with static css selector, and then do something like that:
.parent_css_selector > div:nth-child(1) > div:nth-child(3) > img > input
Token '>' is supposed to look only for direct childs, token ':nth-child' asserts to the child number in parent.
Example:
<div class="parent_css_selector">
<div id="random_id_12312313">
<div id="unneccesary_123123"></div>
<div id="random_id_341234">
<form id="random_id_345545">
<span></span>
<span></span>
<span></span>
<span></span>
<span>
<input id="neccesary_13843942"></input>
</span>
</form>
</div>
</div>
</div>
You can use this selector to access the input:
.parent_css_selector > div > div:nth-child(2) > form > span:nth-child(5) > input

Python - Unable to click button in Selenium under tooltip, webpage throws request error

This is the element I am trying to click (the info button). It's located on pokemongomap.info, and you can see it in chrome devtools under any pokestop or gym.
<a href="#" target="_self" class="tooltip tooltipstered" id="infoboxmoreinfobtnbind" style="display: inline;">
<div id="infoboxmoreinfohit"></div>
<div id="infoboxmoreinfobtn" class="infoboxbtn">
<i class="fa fa-info-circle" aria-hidden="true" style="color: rgb(57, 135, 140);">
</i>
</div>
</a>
I am unable to click it using ActionChains, element.click(), or anything else. If I try to click it using either of those methods, I get a request error from the website. Can anyone help me? Here is some of the code I have tried.
wait = WebDriverWait(driver, 10)
actions = Actions(driver)
element = wait.until(EC.element_to_be_clickable((By.ID, 'infoboxmoreinfobtnbind')))
#element = wait.until(EC.element_to_be_clickable((By.XPATH, '//i[#class="fa fa-info-circle"]'))) also throws error when clicked
#actions.move_to_element(element).click(element).perform() doesn't work either.
action = actions.move_to_element(element)
action.click()
action.perform()
I've also tried clicking on other infobox elements using ActionChains or element.click(), all of them either do nothing or give a request error or aren't clickable at the point.
As a last resort, you can use JS with execute_script:
wait = WebDriverWait(driver, 10)
actions = Actions(driver)
element = wait.until(EC.element_to_be_clickable((By.ID, 'infoboxmoreinfobtnbind')))
driver.execute_script("$(arguments[0]).click();", element)
This is not a humanlike automation but it should do the job...
Hope this helps you!

Get links from a certain div using Selenium in Python

I have the following HTML page. I want to get all the links inside a specific div. Here is my HTML code:
<div class="rec_view">
<a href='www.xyz.com/firstlink.html'>
<img src='imga.png'>
</a>
<a href='www.xyz.com/seclink.html'>
<img src='imgb.png'>
</a>
<a href='www.xyz.com/thrdlink.html'>
<img src='imgc.png'>
</a>
</div>
I want to get all the links that are present on the rec_view div. So those links that I want are,
www.xyz.com/firstlink.html
www.xyz.com/seclink.html
www.xyz.com/thrdlink.html
Here is the Python code which I tried with
from selenium import webdriver;
webpage = r"https://www.testurl.com/page/123/"
driver = webdriver.Chrome("C:\chromedriver_win32\chromedriver.exe")
driver.get(webpage)
element = driver.find_element_by_css_selector("div[class='rec_view']>a")
link = element.get_attribute("href")
print(link)
How can I get those links using selenium on Python?
As per the HTML you have shared to get the list of all the links that are present on the rec_view div you can use the following code block :
from selenium import webdriver
driver = webdriver.Chrome(executable_path=r'C:\chromedriver_win32\chromedriver.exe')
driver.get('https://www.testurl.com/page/123/')
elements = driver.find_elements_by_css_selector("div.rec_view a")
for element in elements:
print(element.get_attribute("href"))
Note : As you need to collect all the href attributes from the div tag so instead of find_element_* you need to use find_elements_*. Additionally, > refers to immediate <a> child node where as you need to traverse all the <a> child nodes so the desired css_selector will be div.rec_view a

I m not able to click on a button in a web page using selenium in python

What is wrong in the below code
import os
import time
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://x.x.x.x/html/load.jsp")
elm1 = driver.find_element_by_link_text("load")
time.sleep(10)
elm1.click()
time.sleep(30)
driver.close()
The page source is
<body>
<div class="formcenterdiv">
<form class="form" action="../load" method="post">
<header class="formheader">Loader</header>
<div align="center"><button class="formbutton">load</button></div>
</form>
</div>
</body></html>
I want to click on button load. when I ran the above code getting this error
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: load
As the documentation says, find_elements_by_link_text only works on a tags:
Use this when you know link text used within an anchor tag. With this
strategy, the first element with the link text value matching the
location will be returned. If no element has a matching link text
attribute, a NoSuchElementException will be raised.
The solution is to use a different selector like find_element_by_class_name:
elm1 = driver.find_element_by_class_name('formbutton')
Did you try using Xpath?
As the OP said, find_elements_by_link_text works on a tags only:
Below code might help you out
driver.get_element_by_xpath("/html/body/div/form/div/button")

Selenium Webdriver finding an element in a sub-element

I am trying to search for an element in a sub-element with Selenium (Version 2.28.0), but selenium des not seem to limit its search to the sub-element. Am I doing this wrong or is there a way to use element.find to search a sub-element?
For an example I created a simple test webpage with this code:
<!DOCTYPE html>
<html>
<body>
<div class=div title=div1>
<h1>My First Heading</h1>
<p class='test'>My first paragraph.</p>
</div>
<div class=div title=div2>
<h1>My Second Heading</h1>
<p class='test'>My second paragraph.</p>
</div>
<div class=div title=div3>
<h1>My Third Heading</h1>
<p class='test'>My third paragraph.</p>
</div>
</body>
</html>
My python (Version 2.6) code looks like this:
from selenium import webdriver
driver = webdriver.Firefox()
# Open the test page with this instance of Firefox
# element2 gets the second division as a web element
element2 = driver.find_element_by_xpath("//div[#title='div2']")
# Search second division for a paragraph with a class of 'test' and print the content
print element2.find_element_by_xpath("//p[#class='test']").text
# expected output: "My second paragraph."
# actual output: "My first paragraph."
If I run:
print element2.get_attribute('innerHTML')
It returns the html from the second division. So selenium is not limiting its search to element2.
I would like to be able to find a sub-element of element2. This post suggests my code should work Selenium WebDriver access a sub element but his problem was caused by a time-out issue.
Can anyone help me understand what is happening here?
If you start an XPath expression with //, it begins searching from the root of document. To search relative to a particular element, you should prepend the expression with . instead:
element2 = driver.find_element_by_xpath("//div[#title='div2']")
element2.find_element_by_xpath(".//p[#class='test']").text
Use the following:
element2 = driver.find_element_by_cssselector("css=div[title='div2']")
element2.find_element_by_cssselector("p[#class='test']").text
Please let me know if you have any problems.
I guess,we need use method "By" from webdriver.common.by when use "driver.find_element".
So...the code must be:
from selenium import webdriver
driver = webdriver.Firefox()
from selenium.webdriver.common.by import By
element2 = driver.find_element(By.XPATH, "//div[#title='div2']")
element2.find_element(By.XPATH, ".//p[#class='test']").text
This is how you search for element or tag in CSS subclass and I believe that it works for multilevel situation as well:
Sample HTML:
<li class="meta-item">
<span class="label">Posted:</span>
<time class="value" datetime="2019-03-22T09:46:24+01:00" pubdate="pubdate">22.03.2019 u 09:46</time>
</li>
This is how you would get pubdate tag value for example.
published = driver.find_element_by_css_selector('li>time').get_attribute('datetime')
Chrome Webdriver :
element = driver.find_element_by_id("ParentElement")
localElement = element.find_element_by_id("ChildElement")
print(localElement.text)
Find The Child of any Elements
parent = browser.find_element(by=By.XPATH,value='value of XPATH of Parents')
child=parent.find_elements(by=By.TAG_NAME,value='value of child path')

Categories

Resources