#java #html #selenium #xpath
Вопрос:
Я работаю над каким-то проектом, в котором мне нужно получить подробную информацию о публикациях в Twitter(лайки, комментарии, ретвиты и просмотры) за последние 10 сообщений. Я следую нижеприведенному подходу:
- Извлекайте сообщения, указав 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);
- Просмотрите каждый пост и получите
<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));
- Но проблема в том, что, когда я хочу получать просмотры для каждого видеопоста(просмотры отображаются только для видео) с помощью 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.
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);
}
}