如何使用Selenium和Python在https://meet.google.com上单击“要求加入”按钮?

问题描述

我正在尝试使用我现有的Google Chrome个人资料在Google Meet链接中单击“要求加入”按钮。这是代码

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

但是未单击加入按钮。按钮上最奇怪的“要求加入”文本确实显示在最后一行。这意味着硒已到达正确的按钮。但是为什么不点击按钮呢?

编辑: 根据@Alin Stelian的回答,我将代码更新如下:

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)

这确实有效,因为两个打印语句都可以工作...但是未单击按钮。这是怎么了?

解决方法


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
,

在您不拥有Selenium的网站上使用时,从不从不依赖ID或类,因为它们经常更改,尤其是对于Google网站而言。

搜索它的最佳方法是找到表示您知道写在按钮上的文本的元素(在本例中为“加入”),然后使所有父级循环,并检查其中是否有某些父级按钮。

赞:

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

然后按周期启动此javascript代码,并仅在父级角色属性等于“按钮”或标签为“按钮”的情况下将其停止

WebElement parent = buttonTextElement;

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

然后单击()。

我已经为您编写了Java的完整代码。我使用的是chromedriver版本85。

我不应该粘贴完整的代码,但我会为你做它:)

我看到“下一个”按钮是第一个父按钮,因此您无需进行递归操作。 PS:自从我访问了意大利语网页以来,请确保字符串“ Next”和“ Ask to Join”正确地代表char。如果需要,请更改

    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; }
                 
             }
            
        }
    
    }

                      
,

对于进一步的自动化项目-避免以编程方式生成值时按id查找元素-不会对您有帮助。另外,长xpaths不利于您的项目性能。

定位器的性能级别为-> ID,CSS,XPATH。

join_butt = WebDriverWait(浏览器,延迟,ignored_exceptions = ignored_exceptions).until(EC.presence_of_element_located((By.XPATH,'// span [contains(text(),'问加入')]'')') ))

稍后修改 下次不要忽略异常-它会帮助您查看错误语法,我对下面的代码进行了测试。

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)

如果Chrome浏览器不允许您登录-这是一个窍门

  1. 运行代码
  2. 在该浏览器中,转到StackOverflow
  3. 使用您的帐户登录
  4. 退出浏览器
  5. 再次运行您的代码-现在,您将自动登录到您的Google帐户。
,

要打印文本要求加入,您需要为visibility_of_element_located()引出WebDriverWait,并且可以使用以下Locator Strategy

  • 使用 XPATH get_attribute()

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

    print(WebDriverWait(driver,"//span[text()='Ask to join']"))).text)
    

您可以在How to retrieve the text of a WebElement using Selenium - Python

中找到相关的讨论

要单击带有文本要加入的元素,您需要为element_to_be_clickable()引出WebDriverWait,并可以使用以下Locator Strategy:>

  • 使用XPATH

    WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"//span[text()='Ask to join']"))).click()
    
  • 注意:您必须添加以下导入:

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

Outro

链接到有用的文档:

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...