Can not find by xpath until inspect the element - selenium

I was using Selenium find_element_by_xpath to click the cookie popup "Accept" button. But it was failing to find the button. So, I tried to locate the button using querySelector in the dev console. Also, the querySelector failed to find the button but after clicking inspect on the button the querySelector able to find the button.
Also, searching the xpath in dev elements just showing 1 of 1.
Why this is happening ? How do I click the "Accept" button using selenium ?
Website link: https://www.transfermarkt.com/
The xpath: //*[#id="notice"]/div[3]/div[2]/button
After inspect on the button.

That element is inside an iframe, so to access it you will first have to switch to that iframe.
You didn't mention what language are you using so I will give my solution in Python. This can be done with other languages as well with some little syntax changes.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 20)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,'iframe[title="SP Consent Message"]')))
wait.until(EC.visibility_of_element_located((By.XPATH, '//button[#title="ACCEPT ALL"]'))).click()
When finished working inside this iframe you will have to switch back to the default content with
driver.switch_to.default_content()

Related

How to click on an image (not button) using Selenium

Before this, I have automated a login into the website howe page. I was stuck trying to make it so that it clicks on the image to navigate to another webpage.
shop_button = driver.find_element(By.XPATH, "/html/body/footer/div/div[2]/a/img")
shop_button.click()
This is the code for the image hyperlink
You can use the below xpath
//p[text()='Shop']//preceding-sibling::img
this should locate the img node, however p tag which has Shop as a text has to be unique in nature.
If it's unique, you can click on it like:
Code trial 1:
time.sleep(5)
driver.find_element(By.XPATH, "//p[text()='Shop']//preceding-sibling::img").click()
Code trial 2:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//p[text()='Shop']//preceding-sibling::img"))).click()
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
PS: time.sleep(5) is just for visualization purpose, you should not use it ideally if code 2 works fine.
You want to redirect to another webpage by clicking on a image. According to the code snippet, I can see that Image tag is inside the tag, you can click on that.
Can you try this ?
shop_button = driver.find_element(By.XPATH,"/html/body/footer/div/div[2]/a")
shop_button.click()
Do let me know if this works.

How to click on SVG element in highcharts to download file using Selenium

My first question was related to this. In the meantime I have found a less efficient workaround. I'd still like automatically download these files.
I would like my script to click on the download icon, click on the Download XLS icon that follows of the page below. The green arrow is where I'd like to click.
The id of the highchart changes every time the page loads. I've tried to fix it it with code sample:
def unityengine_data():
driver.get("https://steamdb.info/tech/Engine/Unity/")
wait
WebDriverWait(driver,30).until(EC.visibility_of_element_located((By.XPATH, "div[contains(#id,'highcharts-')]//*[local-name() = 'svg']/*[name()='g'][6]/*[name()='g']/*[name()='image']"))).click
WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, "div[contains(#id,'highcharts-')]//**[local-name() = 'div']/*[name()='ul'][6]/*[name()='li'][2]"))).click
os.rename("downloaded file path", "new file path")
return "Unity Engine apps data successfully downloaded"
Website image
Website after first click
I hope you can help.
You are simply missing // here at this line
WebDriverWait(driver,30).until(EC.visibility_of_element_located((By.XPATH, "div[contains(#id,'highcharts-')]//*[local-name() = 'svg']/*[name()='g'][6]/*[name()='g']/*[name()='image']"))).click
also, you should ideally create object of WebDriverWait once and reuse it whenever you want.
See the below code, I have improved one locator as well.
Code:
driver.maximize_window()
wait = WebDriverWait(driver, 30)
driver.get("https://steamdb.info/tech/Engine/Unity/")
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[contains(#id,'highcharts-')]//*[local-name() = 'svg']/*[name()='g'][6]/*[name()='g']/*[name()='image']"))).click()
wait.until(EC.visibility_of_element_located((By.XPATH, "//li[text()='Download XLS']"))).click()
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 were almost there. You just need three minor adjustments and one optimization as follows:
You need to add the leading // for an effective xpath.
click is a method so you need to click()
The xpath for the highchart image can be optimized a bit.
The element with text Download XLS is within local-name space, hence you don't need [local-name() = 'div']
Your effective code block will be:
driver.get("https://steamdb.info/tech/Engine/Unity/")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#id,'highcharts-')]//*[local-name() = 'svg']//*[name()='g']//*[name()='image']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#class='highcharts-menu']//li[text()='Download XLS']"))).click()
Browser Snapshot;
References
You can find a couple of relevant detailed discussions in:
How to click on SVG elements using XPath and Selenium WebDriver through Java

Selenium TimeoutException when trying to click Cookies Agree

I am trying to crawl some articles from a website and before doing so, I need to click the "Cookies Agree" using Selenium in Python.
But unfortunately, I keep getting either TimeoutException or NoSuchElementException!
I've figured out that the click button is within iframe, so I've switched to it and clicked the consent button.
homepage = 'link'
driver.maximize_window()
driver.get(homepage)
driver.implicitly_wait(5)
driver.switch_to.frame('location')
try:
consent = wait(driver, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'classname')))
consent.click()
except TimeoutException :
print('timeoutexception')
driver.switch_to.default_content()
iframe
consent click button
But still I just can't get through the TimeoutException error.
What have I done wrong....?!
You mess up wait and driver objects. They are different. Switch to iframe and wait for your button.
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# switch to frame here
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, '.message-component.message-button.no-children:nth-of-type(2)')))
consent = driver.find_element_by_css_selector('.message-component.message-button.no-children:nth-of-type(2)')
consent.click()
There are two .message-component.message-button.no-children css locators and you need the second one.
To find iframe use (this is bulletproof):
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(#id,'sp_message_iframe_')]"))

Finding xpath of an element that appears for a very short amount of time

Is there a good method to find the xpath of an element that only appears very briefly (e.g. for a second or two, like a loading screen).
If I click within an application and a short loading screen appears I would like to find the xpath of the loading element so I can have selenium wait until the element is no longer on the page before continuing.
Sometimes the loading screen appears over the element I want to click and catches the click instead.
Thanks!
Assuming that you are struggling to find XPath of the element that quickly disappears from the page before you could inspect and find the xpath.
You can try opening the console in the webpage by using Ctrl+Shift+I.
Then navigate to the Network tab next to console tab
Below Network tab you will find Online dropdown.
Click on the arrow beside the online dropdown, you will find multiple options click on the one which says Slowest This will reduce the speed of your website loading and gain you more time to find the xpath.
or
You can also customize the throttle by clicking on add option and providing Download, Upload and Latency. or you can directly choose Offline option once your loading icon is enabled.
Attached screenshot for your reference.
Hope this helps.
You can try something like below using web driver wait, not sure which programing language you are using butyou refer same concept with other languages too:
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[contains(text(),'your text1')]")))
Note : please add below imports to your solution
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

How to click on the button with text as Export as per the url through Selenium and Python?

I am stuck and I would love your help. I am not a Python genius, so apologies for the language. I need to click on a button (Export) on this website https://www.fec.gov/data/filings/?data_type=processed&committee_id=C00097485. The button should drive to the bottom of the page where a link to an Excel file appears. Now, I have used this code:
text="//button[#type='button' and contains(.,'Export')]"
driver = webdriver.Firefox()
driver.get("https://www.fec.gov/data/filings/data_type=processed&committee_id=C00142711")
time.sleep(5)
button=driver.find_element_by_xpath(text)
button.click
The script runs fine, no error messages. The website appears, but the 'click' doesnt take place.
I also tried:1) the "wait driver until element is clickable", 2) the ActionChain to move the cursor, 3) to substitute click with sendKeys.
There is no Iframe. I tried also on Chrome. I am using a pc with Windows 10.
What am I doing wrong??? Considering that with other websites, the click function works perfectly fine!
Click is a method so it should be button.click(). You are missing parens.
Also, it would be better if you used WebDriverWait instead of .sleep(), e.g. button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.XPATH, text)));
As per the url the button with text as Export is a JavaScript enabled element, so you need to induce _WebDriverWait_for the element to be clickable and you can use the following solution:
Code Block:
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.Firefox()
driver.get("https://www.fec.gov/data/filings/?data_type=processed&committee_id=C00097485")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.js-export.button.button--cta.button--export"))).click()
Browser Snapshot: