【问题标题】:How to click on the Ask to join button within https://meet.google.com using Selenium and Python?如何使用 Selenium 和 Python 在 https://meet.google.com 中单击“请求加入”按钮?
【发布时间】:2020-12-31 12:28:48
【问题描述】:

我正在尝试单击 google meet 链接中的“Ask to join”按钮(使用我现有的 Google Chrome 个人资料)。这是代码:

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

但是加入按钮没有被点击。按钮上最奇怪的部分“要求加入”文本确实打印在最后一行。这意味着 selenium 已到达正确的按钮。但是为什么还是不点击按钮呢?

编辑: 根据@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)

这确实有效,因为两个打印语句都有效......但是按钮没有被点击。这里出了什么问题?

【问题讨论】:

  • 您的 xpath 不正确,我试过但找不到。我已经分享了正确的 xpath

标签: python-3.x selenium xpath webdriverwait expected-condition


【解决方案1】:

对于进一步自动化项目 - 避免在以编程方式生成值时通过 id 查找元素 - 这对您没有帮助。此外,长 xpath 对您的项目性能不利。

定位器的性能等级是-> 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')]') ))

稍后编辑 下次不要忽略异常——它会帮助你看到你的错误语法,我测试了自己下面的代码。

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 帐户中自动登录。

【讨论】:

  • 我尝试使用此代码..按钮没有被点击..但奇怪的是当我尝试打印它时它确实被打印了
  • @Pranil - 再试一次,我更新了代码,它对我有用。
  • 代码绝对有效!!我尝试打印按钮和其中的文本:join_butt = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.XPATH, "//span[contains(text(),'Ask to join')]"))) print(join_butt) print(join_butt.text) All it is getting print
  • 先生,但问题是,当我尝试使用join_butt.click() 单击按钮时,它没有被单击..可能是什么问题? @Alin Stelian
  • 是的,它确实被打印了..但是按钮没有被点击..
【解决方案2】:

将 Selenium 用于不属于您的网站时,切勿依赖 ID 或类,因为它们经常更改,尤其是对于 google 的网站。

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

像这样:

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

然后在一个循环中启动这个javascript代码,并且只有当父角色属性等于“button”或标签是“button”时才停止它

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

                      

【讨论】:

  • 你写的父代码不起作用兄弟..它返回 None 所以如果我尝试点击它会给我这个错误 AttributeError: 'NoneType' object has no attribute 'click' @Edoardo罗索
  • join_butt = WebDriverWait(browser, delay ,ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.XPATH, '//span[contains(text(),\'Ask to join\')]'))) print(join_butt) join_butt.click() @Edoardo Rosso 这正是 sn-p
  • 这绝对不是我告诉你要尝试的
  • 无论如何你都可以在 Discord SierraLevante#2544 上加我,我有足够的 Selenium 经验来帮助你:)
  • 对不起,先生..其他一些答案建议我在您的回复中发布的代码...但我尝试了 python 版本也是您的 java 代码..它没有工作。这是我试过的代码:buttonTextElement = browser.find_elements_by_xpath("//*[contains(text(), 'Ask to join')]") parent = buttonTextElement parent = browser.execute_script("return arguments[0].parentNode;", parent)
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    要打印文本Ask to join,您需要诱导WebDriverWaitvisibility_of_element_located(),您可以使用以下Locator Strategy

    • 使用 XPATHget_attribute():

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

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

    您可以在How to retrieve the text of a WebElement using Selenium - Python找到相关讨论


    要点击带有文本Ask to join的元素,你需要诱导WebDriverWaitelement_to_be_clickable(),你可以使用下面的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
      

    结尾

    链接到有用的文档:

    【讨论】:

      猜你喜欢
      • 2020-10-03
      • 2021-04-09
      • 2018-08-22
      • 2019-09-01
      • 1970-01-01
      • 2016-12-31
      • 2021-04-07
      • 2019-09-16
      • 1970-01-01
      相关资源
      最近更新 更多