Как правильно найти дочерний элемент веб-элемента в Selenium Java

#java #html #selenium #xpath

Вопрос:

Я работаю над каким-то проектом, в котором мне нужно получить подробную информацию о публикациях в Twitter(лайки, комментарии, ретвиты и просмотры) за последние 10 сообщений. Я следую нижеприведенному подходу:

  1. Извлекайте сообщения, указав Xpath.
          public static final String TWITTER_POST_XPATH = "//*[@class='css-1dbjc4n r-1loqt21 r-18u37iz r-1ny4l3l r-1udh08x r-1qhn6m8 r-i023vh r-o7ynqc r-6416eg']";
    
     List<WebElement> postList = helper.applyFluentWaitByXpathForList(driver, TWITTER_POST_XPATH);
     
  2. Просмотрите каждый пост и получите <div> элемент, содержащий комментарии, лайки и ретвиты.
    В TWITTER_VIRALITY_XPATH я указываю .// , так как div, который я хочу получить, является дочерним элементом элемента post, и он работает нормально, и он дает комментарии, лайки и ретвиты для каждого сообщения.

          public static final String TWITTER_VIRALITY_XPATH = ".//*[@class='css-1dbjc4n r-18u37iz r-1wtj0ep r-1s2bzr4 r-1mdbhws']";
     WebElement virality = postList.get(scroll).findElement(By.xpath(TWITTER_VIRALITY_XPATH));
     
  3. Но проблема в том, что, когда я хочу получать просмотры для каждого видеопоста(просмотры отображаются только для видео) с помощью Xpath, как показано ниже, я могу получать просмотры только для первого видеопоста, для остальной части видеопоста селен не может найти <div> элемент с указанным ниже Xpath.
             public static final String TWITTER_VIEWS_CLASS = ".//*[@class='css-1dbjc4n r-rki7wi r-18u37iz r-161ttwi r-633pao r-u8s1d']";
            WebElement viewsDiv = postList.get(scroll).findElement(By.xpath(TWITTER_VIEWS_CLASS));
     

Поскольку я извлекаю каждый дочерний элемент (лайки, просмотры, комментарии и ретвиты) с помощью его родительского элемента (в моем случае каждое сообщение является родительским элементом), я должен получить сведения о публикации, соответствующие каждому сообщению. Он отлично работает для лайков, комментариев и ретвитов , но не для просмотров (просмотры отображаются по-разному <div> , это означает, что просмотры не встроены в раздел «вирусность», который упоминается в пункте 2).

Я думаю, это потому, что selenium не может получить дочерний элемент «представления» для каждого родительского элемента «сообщение».

Итак, каков наилучший способ получить дочерний веб-элемент веб-элемента с помощью Xpath и, если мой подход верен, почему он работает не для представлений, а для других атрибутов post.

Xpath для всего поста

Xpath for views

Code snippet:

                     //navigating to twitter media page
                WebElement element = helper.applyFluentWaitByXpath(driver,TWITTER_MEDIA_XPATH);
                if(element!=null) {
                    element.click();
                    helper.threadSleep(TEN_THOUSAND_MILLISEC);
                    JavascriptExecutor js = (JavascriptExecutor) driver;
                    List<WebElement> postList = null;
                    
                    try {
                        postList = helper.applyFluentWaitByXpathForList(driver, TWITTER_POST_XPATH);
                       helper.threadSleep(3000);

                    } catch (Exception e) {
                        log.debug("No posts");
                    }

                    int scroll = 0;
                    int i = 0;

                    if (postList != null)
                    while (scroll < postList.size() amp;amp; i < 10) {

                        List<String> postAttributes = new ArrayList<>();

                        WebElement postedOn = postList.get(scroll).findElement(By.tagName("time"));

                        try {
                                postAttributes.add("posted on: "   postedOn.getText());
                        }

                        catch (Exception e) {
                                postAttributes.add("posted on: "   0);
                        }


                        try {
                            
                            WebElement viewsDiv = postList.get(scroll).findElement(By.xpath(TWITTER_VIEWS_CLASS));
                            postAttributes.add("views:"   viewsDiv.getAttribute("innerText")); 
                        }

                        catch (Exception e) {
                            postAttributes.add("views: "   0);
                            System.out.println("views not found");
                            log.debug("views not found");
                        }

                        try {
                            WebElement virality = postList.get(scroll).findElement(By.xpath(TWITTER_VIRALITY_XPATH));

                            if (virality != null) {

                                try {
                                    List<WebElement> divList = virality.findElements(By.xpath(TWITTER_DIV_LIST));

                                    try {
                                        WebElement spanParent = divList.get(0).findElement(By.tagName(SPAN));
                                        WebElement spanChild = spanParent.findElement(By.tagName(SPAN));
                                        postAttributes.add("comments: "   spanChild.getText());
                                    } catch (Exception e) {
                                        log.debug("Comments not found");
                                        postAttributes.add("comments: "   0);
                                    }

                                    try {
                                        WebElement spanParent = divList.get(1).findElement(By.tagName(SPAN));
                                        WebElement spanChild = spanParent.findElement(By.tagName(SPAN));
                                        postAttributes.add("retweets: "   spanChild.getText());
                                    } catch (Exception e) {
                                        log.debug("Retweets not found");
                                        postAttributes.add("retweets: "   0);
                                    }

                                    try {
                                        WebElement spanParent = divList.get(2).findElement(By.tagName(SPAN));
                                        WebElement spanChild = spanParent.findElement(By.tagName(SPAN));
                                        postAttributes.add("likes: "   spanChild.getText());
                                    } catch (Exception e) {
                                        log.debug("likes not found");
                                        postAttributes.add("likes: "   0);
                                    }
                                } catch (NoSuchElementException e) {
                                    log.debug("Div list for virality not found");
                                }
                            }
                        }

                        catch (Exception e) {
                            log.debug("virality not found");
                        }

                        scroll  ;
                        i  ;
                        postData.put("post"   i, postAttributes);

                        if (scroll == postList.size()) {
                            try {
                                helper.threadSleep(2000);
                                js.executeScript("window.scrollTo(0, 5000)");
                                postList = helper.applyFluentWaitByXpathForList(driver, TWITTER_POST_XPATH);
                                scroll = 0;

                            } 
                            
                            catch (Exception e) {
                                log.debug("No posts");
                            }
                        }

                        helper.threadSleep(3000);
                    }
                }