How to click on the Ask to join button within https://meet.google.com using Selenium and Python?

不问归期 提交于 2021-02-15 06:51:26

问题


I am trying to click the Ask to join button in a google meet link(using my existing Google Chrome profile).This is the code:

options = webdriver.ChromeOptions()
options.add_argument(r"--user-data-dir=C:\\Users\\Pranil.DESKTOP-TLQKP4G.000\\AppData\\Local\\Google\\Chrome\\User Data")
browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)
delay = 15
browser.get('https://meet.google.com/tws-kcie-aox')
ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,)
time.sleep(5)
join_butt = WebDriverWait(browser, delay ,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.XPATH, '//*[@id="yDmH0d"]/c-wiz/div/div/div[5]/div[3]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div')))
join_butt.click()
print(join_butt.text)#this prints Ask to join

But the join button is not getting clicked. The most weird part 'Ask to join' text on the button does get printed in the last line. This means that selenium has reached the correct button. But still why does it not click the button?

EDIT: According to an answer by @Alin Stelian I updated the code as follows:

browser.get('https://meet.google.com/hst-cfck-kee')
browser.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 'd')
join_butt = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.XPATH, "//span[contains(text(),'Ask to join')]")))
join_butt.click()
print(join_butt)
print(join_butt.text)

This does work as both the print statements work...But the button isn't getting clicked. What is going wrong over here?


回答1:


For further automating projects - avoid finding elements by id when the value is generated programmatically - it will not help you. Also, long xpaths is bad for your project performance.

The performance level of locators is -> ID, CSS, XPATH.

join_butt = WebDriverWait(browser, delay ,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.XPATH, '//span[contains(text(),'Ask to join')]')))

later edit next time don't ignore exceptions - it will help you to see your error syntax, I tested myself the below code.

join_butt = WebDriverWait(browser, delay).until(
    EC.presence_of_element_located((By.XPATH, "//span[contains(text(),'Ask to join')]")))
driver.execute_script("arguments[0].click();", join_butt)

If the chrome browser doesn't allow you to log in - here is a trick

  1. Run your code
  2. In that browser go to StackOverflow
  3. Login w/ your account
  4. Quit the browser
  5. Run again your code - now you'll be logged in automatically in your google account.



回答2:



You can use the quickest path 
//span[contains(text(),'Ask to join')]

or from your code correct xpath
//*[@id="yDmH0d"]/c-wiz/div/div/div[4]/div[3]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div/span/span

your xpath in the Code
//*[@id="yDmH0d"]/c-wiz/div/div/div[5]/div[3]/div/div[2]/div/div/div[2]/div/div[2]/div/div[1]/div



回答3:


When using Selenium for website that you don't own, NEVER rely on IDs or classes since they often change, especially for google's websites.

Best way to search for it is to find the element that presents the text that you know is wrote on the button (in this case Ask to join) and then get all the parents in a loop and check if some of them are buttons.

Like this:

WebElement buttonTextElement = browser.find_elements_by_xpath("//*[contains(text(), 'Ask to join')]")

then launch this javascript code in a cycle and stop it only if parent role attribute is equal to "button" or tag is "button"

WebElement parent = buttonTextElement;

WebElement parent = browser.execute_script("return arguments[0].parentNode;", parent) 

Then click().

I've wrote for u a fully working code in Java. I've used chromedriver version 85.

I shouldn't paste a whole code, but i'll do it for u :)

I saw that "Next" Button is the first parent so you don't need to go recursive. PS: Since i visited the italian webpage, make sure that the strings "Next" and "Ask to Join" are right char for char. Change them if u need to.

    import java.util.ArrayList;
    import org.openqa.selenium.By;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.chrome.ChromeDriver;
    import org.openqa.selenium.chrome.ChromeOptions;
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            
            String email = "Your Google Email";
            
            String pass = "Your Google Password";
            
    
            System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
    
            ChromeOptions options = new ChromeOptions();
            
            
            // You need this to stop the page from askin u for mic
            options.addArguments("--use-fake-ui-for-media-stream");
            
            WebDriver driver = new ChromeDriver(options);
    
            
            //Login to Google
            driver.get("https://accounts.google.com/login");
            
            ArrayList<WebElement> emailinput = new ArrayList<WebElement>();
            
            ArrayList<WebElement> spans = new ArrayList<WebElement>();
            
             emailinput = (ArrayList<WebElement>) driver.findElements(By.tagName("input"));
             
             //Get all spans in page
             spans = (ArrayList<WebElement>) driver.findElements(By.tagName("span"));
            
             for(int i = 0; i < emailinput.size(); i++) {
                 
                 if(emailinput.get(i).getAttribute("type").equals("email")) { emailinput.get(i).sendKeys(email); break; }
                 
             }
             
             for(int i = 0; i < spans.size(); i++) {
                 
                 if(spans.get(i).getText().equals("Next")) {
                 WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
                         "return arguments[0].parentNode;", spans.get(i)); parent.click(); break; }
                 
             }
             
             
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            ArrayList<WebElement> passinput = (ArrayList<WebElement>) driver.findElements(By.tagName("input"));
            
             for(int i = 0; i < passinput.size(); i++) {
                 
                 if(passinput.get(i).getAttribute("type").equals("password")) { passinput.get(i).sendKeys(pass); break; }
                 
             }
             
             spans = (ArrayList<WebElement>) driver.findElements(By.tagName("span"));
             
            
             for(int i = 0; i < spans.size(); i++) {
                 
                 if(spans.get(i).getText().equals("Next")) {
                 WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
                         "return arguments[0].parentNode;", spans.get(i)); parent.click(); break; }
                 
             }
             
             try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             


//Create a Meet room and put here its URL
             driver.navigate().to("https://meet.google.com/dxz-dbwt-tpj");
             
             try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             
             spans = (ArrayList<WebElement>) driver.findElements(By.tagName("span"));
                
             for(int i = 0; i < spans.size(); i++) {
                 
                 if(spans.get(i).getText().equals("Ask to Join")) {
                 WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
                         "return arguments[0].parentNode;", spans.get(i)); parent.click(); break; }
                 
             }
            
        }
    
    }

                      



回答4:


To print the text Ask to join you need to induce WebDriverWait for the visibility_of_element_located() and you can use the following Locator Strategy:

  • Using XPATH and get_attribute():

    print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//span[text()='Ask to join']"))).get_attribute("innerHTML"))
    
  • Using XPATH and text attribute:

    print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//span[text()='Ask to join']"))).text)
    

You can find a relevant discussion in How to retrieve the text of a WebElement using Selenium - Python


To click on the element with text Ask to join you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following Locator Strategy:

  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "//span[text()='Ask to join']"))).click()
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

Outro

Link to useful documentation:

  • get_attribute() method Gets the given attribute or property of the element.
  • text attribute returns The text of the element.
  • Difference between text and innerHTML using Selenium


来源:https://stackoverflow.com/questions/63873200/how-to-click-on-the-ask-to-join-button-within-https-meet-google-com-using-sele

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!