Basically, I want to acess acess a button that appears in a print preview pop up, which is a shadow dom element. I tried some solutions I found around stackoverflow, but they didn't work, just as the current code I'm trying to build up from, which is:
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
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
def expand_shadow_root(element):
shadow_root = driver.execute_script("return arguments[0].shadowRoot", element)
return shadow_root
root1 = driver.find_element_by_tag_name("print-preview-button-strip")
shadow_root1 = expand_shadow_root(root1)
btn = shadow_root1.find_element_by_xpath("/html/body/print-preview-app//print-preview-sidebar//print-
preview-button-strip//cr-button[1]")
wait.until((EC.element_to_be_clickable(By.XPATH,"/html/body/print-preview-app//print-preview-
sidebar//print-preview-button-strip//cr-button[1]")))
btn.click()
Inspect Element print
try below xpath :
//cr-button[#class='action-button' and #role='button']
In case anyone has the same problem, just insert "-kiosk-printing" as an argument, like this:
options = webdriver.ChromeOptions()
options.add_argument("-kiosk-printing")
driver = webdriver.Chrome(options=options)
Solved the problem for me.
Related
I am trying to get the webdriver to click a button on the site random.org The button is a generator that generates a random integer between 1 and 100. It looks like this:
After inspecting the webpage, I found the corresponding element on the webpage looks something like this:
It is inside an iframe and someone suggested that I should first switch over to that iframe to locate the element, so I incorporated that in my code but I am constantly getting NoSuchElementException error. I have attached my code and the error measage below for your reference. I can't understand why it cannot locate the button element despite referencing the ID, which is supposed to unique in the entire document.
The code:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.get("https://www.random.org/")
driver.implicitly_wait(15)
driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))
button = driver.find_element(By.CSS_SELECTOR, "input[id='hnbzsqjufzxezy-button']")
button.click()
The error message:
Make sure that there are no more Iframes on the page. If there are a few an not only one do this:
iframes = driver.find_elements(By.CSS, 'iframe')
// try switching to each iframe:
driver.switch_to.frame(iframes[0])
driver.switch_to.frame(iframes[1])
You can't find the button because its name contain random letters. Every time you will refresh the page you can see that the name value will change. So, do this:
button = driver.findElement(By.CSS, 'input[type="button"][value="Generate"]')
button.click()
There are several issues with your code:
First you need to close the cookies banner
The locator of the button is wrong. It's id is dynamic.
You need to use WebDriverWait to wait for elements clickability.
The following code works:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("start-maximized")
webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(service=webdriver_service, options=options)
url = 'https://www.random.org/'
driver.get(url)
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[onclick*='all']"))).click()
wait.until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME, "iframe")))
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id*='button']"))).click()
I'm attempting to click the next page button on this site. I've looked at multiple proposed solutions on Stack Overflow for similar issues, but none of them seem to work. This is my current code as of now:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
next_button = wait.until(EC.element_to_be_clickable((By.XPATH, "html/body/div/div/div/main/div[3]/div[2]/div/div[3]/div[1]/div[2]/div[2]/div/div[1]/div[3]/button[2]/i/svg")))
driver.execute_script("return arguments[0].scrollIntoView();", next_button)
next_button.click()
Any help would be appreciated. Thank you!
I have written this code to replicate your scenario and it is working fine. I have used the xpath which search for svg element with some class name. The problem with the website is, there are many duplicate elements present in it. Because of that might be your code is not working. Please try below code.
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
driver = webdriver.Chrome(options=options)
driver.get('https://rotogrinders.com/resultsdb/site/draftkings/date/2018-07-02/sport/mlb/slate/'
'5b3aafe73870401e20652804/contest/5b3aafe83870401e20652b84')
wait = WebDriverWait(driver, 30)
# Find Next Button and Click
Next_Button = wait.until(EC.element_to_be_clickable(
(By.XPATH, "(//*[local-name()='svg' and #data-icon='right'])[2]/ancestor::button")))
Next_Button.click()
Do let me know if you have any queries?
You may try as follows:
wait = WebDriverWait(driver, 10)
next_button = wait.until(EC.element_to_be_clickable((By.XPATH, '(//*[#class="anticon anticon-right"])[2]')))
driver.execute_script("return arguments[0].scrollIntoView();", next_button)
next_button.click()
I am using selenium to try to scrape data from a website (https://www.mergentarchives.com/), and I am attempting to get the innerText from this element:
<div class="x-paging-info" id="ext-gen200">Displaying reports 1 - 15 of 15</div>
This is my code so far:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.maximize_window()
search_url = 'https://www.mergentarchives.com/search.php'
driver.get(search_url)
assert 'Mergent' in driver.title
company_name_input = '//*[#id="ext-comp-1009"]'
search_button = '//*[#id="ext-gen287"]'
driver.implicitly_wait(10)
driver.find_element_by_xpath(company_name_input).send_keys('3com corp')
driver.find_element_by_xpath(search_button).click()
driver.implicitly_wait(20)
print(driver.find_element_by_css_selector('#ext-gen200').text)
basically I am just filling out a search form, which works, and its taking me to a search results page, where the number of results is listed in a div element. When I attempt to print the text of this element, I simply get a blank space, there is nothing written and no error.
[Finished in 21.1s]
What am I doing wrong?
I think you may need explicit Wait :
wait = WebDriverWait(driver, 10)
info = wait.until(EC.visibility_of_element_located((By.XPATH, "//div[#class = 'x-paging-info' and #id='ext-gen200']"))).get_attribute('innerHTML')
print(info)
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
You may need to put a condition by verifying if search results loaded or not and once its loaded you can use below code
print(driver.find_element_by_id('ext-gen200').text)
I'm trying to get to the results page of a search but I have to first click on the dropdown option to complete the search. When I do this manually, the dropdown hides if I do not click on it right as it appears, when I code it, I get a the following error:
ElementNotInteractableException: Message: Element <div id="_esgratingsprofile_autocomplete-results-container" class="autocomplete-results-container msci-ac-search-data-dropdown"> could not be scrolled into view
This is my code so far, you can visit the url and see how it is yourself as well:
from selenium.webdriver import Firefox
from selenium.webdriver.support.ui import Select
from selenium.webdriver.firefox.options import Options
opts = Options()
opts.set_headless()
assert opts.headless
browser = Firefox(options=opts)
browser.get('https://www.msci.com/esg-ratings')
search_form = browser.find_element_by_id('_esgratingsprofile_keywords')
search_form.send_keys('MSFT')
browser.find_element_by_xpath("//div[#id='_esgratingsprofile_autocomplete-results-container']/ul[#id='ui-id-1']/li[#class='msci-ac-search-section-title ui-menu-item']").click()
I looked through many other answers but they didnt seem to deal with the case where the dropdown was not a directly clickable element or where it hides if you dont click on it right away. Any help is appreciated.
Try the below code, This code is working for me. Let me know if it shows any error.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.maximize_window()
wait = WebDriverWait(driver, 5)
action = ActionChains(driver)
driver.get("https://www.msci.com/esg-ratings")
Drop_Down = driver.find_element_by_xpath('//*[#id="_esgratingsprofile_keywords"]')
Drop_Down.send_keys("MSFT")
# Select the First Result from the search.
Result = wait.until(
EC.presence_of_element_located((By.XPATH, "//div[contains(#class,'autocomplete-results-container')]/ul/li[1]")))
action.move_to_element(Result).click().perform()
I've written a script in Python in association with selenium to keep clicking on MORE button to load more items until there are no new items left to load from a webpage. However, my below script can click once on that MORE button available on the bottom of that page.
Link to that site
This is my try so far:
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
link = "https://angel.co/companies?company_types[]=Startup&company_types[]=Private+Company&company_types[]=Mobile+App&locations[]=1688-United+States"
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get(link)
while True:
for elems in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,".results .name a.startup-link"))):
print(elems.get_attribute("href"))
try:
loadmore = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,"[class='more']")))
driver.execute_script("arguments[0].scrollIntoView();", loadmore)
loadmore.click()
except Exception:break
driver.quit()
How can I keep clicking on that MORE button until there are no such button left to click and parse the links as I've already tried using for loop.
I've managed to solve the problem pursuing sir Andersson's logic within my exising script. This is what the modified script look like.
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
link = "https://angel.co/companies?company_types[]=Startup&company_types[]=Private+Company&company_types[]=Mobile+App&locations[]=1688-United+States"
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get(link)
while True:
try:
loadmore = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,"[class='more']")))
driver.execute_script("arguments[0].click();", loadmore)
wait.until(EC.staleness_of(loadmore))
except Exception:break
for elems in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,".results .name a.startup-link"))):
print(elems.get_attribute("href"))
driver.quit()
why not just?
while (driver.FindElements(By.ClassName("more")).Count > 0)
{
driver.FindElement(By.ClassName("more")).Click();
//Some delay to wait lazyload to complete
}
c# example. pretty sure that it can be done with python as well