Python Selenium click google "I agree" button - python

I am trying to scrape some google data but I first want to click the 'I agree' button that google pops up. This is the script I use to do that:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
search_question = input("Ask a question: ")
driver = webdriver.Chrome("*Your Webdriver location*")
driver.wait = WebDriverWait(driver, 5)
driver.get("https://google.com")
time.sleep(1)
agree = driver.wait.until(EC.presence_of_element_located((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
# time.sleep(0.2)
search = driver.find_element_by_class_name("gLFyf")
search.send_keys(search_question)
search.send_keys(Keys.ENTER)
The problem is selenium doesn't seem to locate the button and therefore I get a timeout error. (I have tried also with find_element_by_xpath and still not working).

If you scroll up in the devtools inspector you'll notice that your element is within an iframe:
You need to switch to that frame first, click your button then switch back to the default content (the main page)
driver.get("https://google.com")
#active the iframe and click the agree button
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe")))
agree = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
#back to the main page
driver.switch_to_default_content()
That works for me.
FYI - There's only 1 iframe on the page, that's why the xpath //iframe works. If there were multiple you'd need to identify it with higher accuracy.

If you already have been agreed,then agree button would not appear. That why it is not be able to find given XPath.
Try this:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
search_question = input("Ask a question: ")
driver = webdriver.Chrome(".\chromedriver.exe")
driver.wait = WebDriverWait(driver, 5)
driver.get("https://google.com")
time.sleep(3)
# agree = driver.wait.until(EC.presence_of_element_located((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
# agree.click()
# time.sleep(0.2)
search = driver.find_element_by_class_name("gLFyf")
search.send_keys(search_question)
search.send_keys(Keys.ENTER)

Managed to get it working.
Seems like one of the few elements that are interactive in the popup when you first load the site is the language dropdown, which I found by class name.
Then the Agree button is detectable and you can find it by class too.
driver.get("https://www.google.com")
driver.maximize_window()
time.sleep(2)
#finds+clicks language dropdown, interaction unhides the rest of the popup html
driver.find_element_by_class_name('tHlp8d').click()
time.sleep(2)
#finds+clicks the agree button now that it has become visible
driver.find_element_by_id('L2AGLb').click()
you should now have the standard searchbar etc

i had some problems with clicking pop-ups and the problem turned out to be with that click().
im not sure that it might be the same issue with urs or not but try changing ur click to this :
agree = driver.find_element_by_xpath('//*[#id="introAgreeButton"]/span/span')
driver.execute_script("arguments[0].click();", agree)

The problem was that it didn't change frames here is the soulution code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome('C:\\Users\\gassp\\OneDrive\\Namizje\\Python.projects\\chromedriver.exe')
url = 'https://www.google.com/maps/'
driver.get(url)
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//*[#id="consent-bump"]/div/div[1]/iframe')))
agree = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
#back to the main page
driver.switch_to_default_content()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="searchboxinput"]'))).send_keys('gostilne')
driver.submit()

Related

Python Selenium driver.find_element().text returns empty string, but text is visible in the driver.page_source

I'm trying to scrape some titles of the videos and to do so I'm using Selenium, but I've encountered a problem. driver.find_element().text returns empty string, but title is for sure located in given XPATH. Here is the fragment of the page source returned by driver.page_source:
<div class="title">Big.Sky.S03E01.ITA.WEBDL.1080p</div>
To find the title I am trying to use:
hoverable = driver.find_element(By.XPATH, '//*[#id="videojs"]/div[1]')
ActionChains(driver).move_to_element(hoverable).perform()
wait = WebDriverWait(driver, 20)
title_from_url = wait.until(EC.visibility_of_element_located((By.XPATH, '/html/body/div[1]/a'))).text
title_from_url = driver.find_element(
By.XPATH, '/html/body/div[1]/a'
).text.casefold()
From what I've read it could be caused by the fact that the page might not be fully loaded (I wasn't using any wait condition here). After that I've tried to add a wait condition and even time.sleep(), but it didn't change anything. <mini question: how would proper wait staitment look like here?>
Edit:
I think the problem is caused, because title is showing up only when mouse is in the player area. I think some mouse movement will be needed here, but I have tried to move mouse into the player area and for some time it is working but after a while there is a moment when title will disappear too fast. Is there a way to use find_element() while also moving mouse?
Any help will be appreciated.
Best regards,
Ed.
Example site: https://mixdrop.to/e/4n3x7e31hpwxm8.
You have to wait for element to be completely loaded before extracting it text content. WebDriverWait expected_conditions explicit waits should be used for that.
This should wait in case the element is visible on the page and the locator is correct:
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, 20)
title_from_url = wait.until(EC.visibility_of_element_located((By.XPATH, '//div[contains(#class, "title")]/a'))).text
UPD
In case the element content is dynamically changes and we need to hover over that element to make the desired text to appear there, we can simulate the mouse hover action with the help of ActionChains module.
The tool-tip etc. will not disappear until you perform some click etc. on that page. So, just performing a background action of driver.find_element() will not affect that text.
UPD2
The title element is not visible. It becomes visible only by hovering over the player.
Here I'm performing such hovering and then getting the title text:
from selenium import webdriver
from selenium.webdriver import ActionChains
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(options=options, service=webdriver_service)
wait = WebDriverWait(driver, 5)
actions = ActionChains(driver)
url = "https://mixdrop.to/e/4n3x7e31hpwxm8"
driver.get(url)
player = wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'player')))
actions.move_to_element(player).perform()
title = wait.until(EC.presence_of_element_located((By.XPATH, '//div[contains(#class, "title")]/a')))
print(title.text)
The output is:
Big.Sky.S03E01.ITA.WEBDL.1080p
If you suspect its because of sync issue. You can use selenium waits.Let it be implicit of explicit.
Implicit:
objdriver.implicitely_wait(float)
Explicit:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
objwait=WebDriverWait(driver,float,poll_frequency=float,ignored_exception=float)
objelement=objwait.until(EC.visibility_of_element_located((By.XPATH,"Your XPATH")))

Changing country while scraping Aliexpress using python selenium

I'm working on a scraping project of Aliexpress, and I want to change the ship to country using selenium,for example change spain to Australia and click Save button and then scrap the page, I already found an answer it worked just I don't know how can I save it by clicking the button save using selenium, any help is highly appreciated. This is my code using for this task :
country_button = driver.find_element_by_class_name('ship-to')
country_button.click()
country_buttonn = driver.find_element_by_class_name('shipping-text')
country_buttonn.click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[#class='address-select-item ']//span[#class='shipping-text' and text()='Australia']"))).click()
Well, there are 2 pop-ups there you need to close first in order to access any other elements. Then You can select the desired shipment destination. I used WebDriverWait for all those commands to make the code stable. Also, I used scrolling to scroll the desired destination button before clicking on it and finally clicked the save button.
The code below works.
Just pay attention that after selecting a new destination pop-ups can appear again.
import time
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
from selenium.webdriver.common.action_chains import ActionChains
options = Options()
options.add_argument("--start-maximized")
s = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(options=options, service=s)
url = 'https://www.aliexpress.com/'
wait = WebDriverWait(driver, 10)
actions = ActionChains(driver)
driver.get(url)
try:
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#style,'display: block')]//img[contains(#src,'TB1')]"))).click()
except:
pass
try:
wait.until(EC.element_to_be_clickable((By.XPATH, "//img[#class='_24EHh']"))).click()
except:
pass
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "ship-to"))).click()
wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "shipping-text"))).click()
ship_to_australia_element = driver.find_element(By.XPATH, "//li[#class='address-select-item ']//span[#class='shipping-text' and text()='Australia']")
actions.move_to_element(ship_to_australia_element).perform()
time.sleep(0.5)
ship_to_australia_element.click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[#data-role='save']"))).click()
I mostly used XPath locators here. CSS Selectors could be used as well

Button click using selenium webdriver youtbe example

When I run the code, it opens the browser, but I want to click the reject all button when the cookie banner comes from YouTube. I tried using class and a link text. It did not work.
I will appreciate any help.
from selenium import webdriver
from selenium.webdriver.common.by import By
url = 'https://www.youtube.com/'
driver = webdriver.Chrome(executable_path="C:\\Users\\donner\\Downloads\\chromedriver_win32\\chromedriver.exe")
driver.get(url)
driver.implicitly_wait(100)
continue_link = driver.find_element(By.LINK_TEXT, "Reject all")
continue_link.click()
driver.implicitly_wait(100)
content = driver.find_element(By.CLASS_NAME, '.style-scope.ytd-button-renderer.style-primary size-default')
content.click()
Try the below xpath with the given code
//*[normalize-space()='Reject all']
OR
//*[contains(text(),'Reject all')]
The Code:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "myXpath")))
element.click();
The above soultion work if there is no iframe
In case there is iframe, than you need to follow below
WebDriverWait(driver,20).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"iframe")))
driver.find_element(By.XPATH, "yourXpath").click()

ElementNotInteractableException: element not interactable in Selenium

I am trying to get the review of a certain product but it returns an error.
My code:
import selenium
from selenium import webdriver
chrome_path = r"C:\Users\AV\AppData\Local\Programs\Python\Python39\Scripts\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://oldnavy.gapcanada.ca/browse/product.do?pid=647076053&cid=1180630&pcid=26190&vid=1&nav=meganav%3AWomen%3ADeals%3ASale&grid=pds_0_1034_1#pdp-page-content")
driver.execute_script("window.scrollTo(0, 1000)")
import time
from time import sleep
sleep(5)
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.promoDrawer__handlebar__icon"))).click()
review = driver.find_elements_by_class_name("pr-rd-description-text")
for post in review:
print(post.text)
driver.find_element_by_xpath('//*[#id="pr-review-display"]/footer/div/div/a').click()
review2 = driver.find_elements_by_class_name("pr-rd-description-text")
for post in review2:
print(post.text)
It returns: selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
Can you please tell me what should I do?
The button is really hard to click.
I guess it could be achieved by adding some more waits and moving with ActionChains class methods.
I could click it with Javascript code with no problems.
What it does:
1 Scrolls to the Next button
2 Clicks it.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')
driver.get(
"https://oldnavy.gapcanada.ca/browse/product.do?pid=647076053&cid=1180630&pcid=26190&vid=1&nav=meganav%3AWomen%3ADeals%3ASale&grid=pds_0_1034_1#pdp-page-content")
driver.execute_script("window.scrollTo(0, 1000)")
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.promoDrawer__handlebar__icon"))).click()
wait.until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".pr-rd-description-text")))
review = driver.find_elements_by_css_selector(".pr-rd-description-text")
for post in review:
print(post.text)
# wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".pr-rd-pagination-btn"))).click()
element = driver.find_element_by_css_selector(".pr-rd-pagination-btn")
# actions = ActionChains(driver)
# actions.move_to_element(element).click().perform()
driver.execute_script("arguments[0].scrollIntoView();", element) # Scrolls to the button
driver.execute_script("arguments[0].click();", element) # Clicks it
print("clicked next")
I also rearranged your code, moved imports to the beginning of the file, got rid of unpredictable time.sleep() and used more reliable css locators. However, your locator should also work.
I left the options I tried commented out.
That element is weird. Even when I scroll into view, use actions to click it, or execute javascript to click, it doesn't work. What I would suggest is just grabbing the href attribute from the element and going to that URL, using something like this:
driver.get(driver.find_element_by_xpath('//*[#id="pr-review-display"]/footer/div/div/a').get_attribute('href'))

Popup window on youtube - how to close with selenium

Could you please help me with one issue? I have got a problem with Selenium and popup windows with agreements on youtube.
When first window is jumped - Selenium close this window, but if I want to close second window/frame, selenium doesn't work. Could you please help?
The part of code attached below:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from time import sleep
class YoutubeSearcher:
def __init__(self, search):
self.search = search
def open_url(self) -> None:
driver = webdriver.Chrome()
driver.get('https://www.youtube.com/')
try:
WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH, '/html/body/ytd-app/ytd-popup-container/paper-dialog/yt-upsell-dialog-renderer/div/div[3]/div[1]/yt-button-renderer/a/paper-button/yt-formatted-string'))).click()
except:
print("no alert to accept")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[#id="yDmH0d"]/c-wiz/div[2]/div/div/div/div/div[2]/form'))).click()
search = driver.find_element_by_id("search")
search.clear()
search.send_keys(self.search)
submit_button = driver.find_element_by_id("search-icon-legacy")
submit_button.click()
From the code you have share these are my observations :
First popup.
WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH, '/html/body/ytd-app/ytd-popup-container/paper-dialog/yt-upsell-dialog-renderer/div/div[3]/div[1]/yt-button-renderer/a/paper-button/yt-formatted-string'))).click()
Second popup.
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="yDmH0d"]/c-wiz/div[2]/div/div/div/div/div[2]/form'))).click()
Suggestion :
Check the xpath once if they are correct or are there multiple locators which are being returned.
Add apprropriate waits : like isVisible,clickable for both the locator popup.
Using basic if else you can make the conditions work (no specific need of try except).
After one popup is closed check if the next popup is visible or not.
This is the code that finally works. A switching frame is needed for the second pop up. It's lame, I know but it works.
Hope it helps. Good luck.
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from time import sleep
driver = webdriver.Chrome('C:\Webdrivers\chromedriver.exe')
driver.maximize_window()
driver.get('https://www.youtube.com')
WebDriverWait(driver, 5).until(
EC.element_to_be_clickable((By.XPATH,
'/html/body/ytd-app/ytd-popup-container/paper-dialog/yt-upsell-dialog-renderer/div/div[3]/div[1]/yt-button-renderer/a/paper-button/yt-formatted-string'))).click()
driver.switch_to.frame(0)
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,"/html/body/div/c-wiz/div[2]/div/div/div/div/div[2]/form/div/span/span"))).click()

Categories