我观察到的是,内容已经加载到页面中,当我们向下滚动时它会显示给我们。
但是如果我们通过使用类名'next'手动加载页面来检查'Next>'按钮,例如如下所示,
//按钮[@class='next']
在我们向下滚动之前我们无法找到它,因为它对我们不可见。但是通过使用下面的 XPath,我们可以识别所有的配置文件链接计数,无论它们是否显示?
//h3[contains(@class, 'search-results__total')]/parent::div/ul/li
当您想从页面中获取所有配置文件链接时,我们可以使用上面的 XPath 帮助来做到这一点。我们将使用上面的 XPath 获取链接计数,然后我们将一次滚动到每个元素视图,然后我们将按如下方式获取配置文件链接:
// Identifying the all the profile links
List<WebElement> totalProfileLinks = driver.findElements(By.xpath("//h3[contains(@class, 'search-results__total')]/parent::div/ul/li"));
// Looping for getting the profile link
for(int i=1;i<totalProfileLinks.size();i++) {
// Scrolling so that it will be visible
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", totalProfileLinks.get(i));
// Fetching the anchor node
final WebElement link = driver.findElement(By.xpath("(//h3[contains(@class, 'search-results__total')]/parent::div/ul/li//div[contains(@class, 'search-result__info')]//a)["+i+"]"));
// Avoiding the StaleElementReferenceException
new FluentWait<WebDriver>(driver).withTimeout(1, TimeUnit.MINUTES).pollingEvery(1, TimeUnit.SECONDS).ignoring(StaleElementReferenceException.class).until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver arg0) {
return link;
}
});
// Fetching and printing the link from anchor node
System.out.println(link.getAttribute("href").trim());
}
所以,如果我们想首先单击“下一步”按钮,我们需要检查它是否存在(当我们在获取配置文件链接时滚动时,“下一步”按钮也会显示)。我们可以使用 `driver.findElements();` 方法来获取该元素计数的匹配项,并将其存储在一些列表中(因为它返回 WebElements 列表),如下所示:
List<WebElement> nextButton = driver.findElements(By.className("next"));
使用上述技术的好处是,如果没有元素匹配,脚本也不会失败,如果没有匹配,我们将有一个空列表。
然后我们可以使用 List 接口的 size() 方法来获取匹配数,如下所示:
int size = nextButton.size();
如果大小大于 0,则该元素存在,否则不存在,我们可以检查该条件,如下所示:
if(size > 0) {
nextButton.get(0).click(); // Do some operation like clicking on it
System.out.println("=> 'Next >' button is there and clicked on it...");
} else {
System.out.println("=> 'Next >' button is NOT there...");
}
当内容被加载并且元素可见时,我们将使用 JavaScriptExecutor 来定位并点击它。
将上述代码包装在 while 循环中,并在每次单击上一个“下一步 >”按钮后检查是否存在“下一步 >”按钮,如下所示:
boolean next = true;
while(next) {
// Checking 'Next >' button is there or not in the page
List<WebElement> nextButton = driver.findElements(By.className("next"));
// If the 'Next >' button is there then clicking on it otherwise stopping the execution
if(nextButton.size() > 0) {
doClickUsingJSE(nextButton.get(0));
System.out.println("=> 'Next >' button is there and clicked on it...");
} else {
next = false;
System.out.println("=> 'Next >' button is NOT there so stopping the execution...");
}
Thread.sleep(1000);
}
如果上述代码中的“if”条件失败,循环将中断,因为“next”将变为“false”。如果我们使用 Fluent Wait,那么它将帮助我们避免一些“异常”,例如“WebDriverException”和“StaleElementReferenceException”。所以我写了一个单独的方法,它会通过避免一些异常来等待一个元素,如果条件得到满足就点击它。
检查下面的代码:
private static void doClickUsingJSE(final WebElement element) {
// Using the Fluent Wait to avoid some exceptions like WebDriverException and StaleElementReferenceException
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(1, TimeUnit.MINUTES).pollingEvery(1, TimeUnit.SECONDS).ignoring(WebDriverException.class, StaleElementReferenceException.class);
WebElement waitedElement = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return element;
}
});
wait.until(ExpectedConditions.visibilityOf(waitedElement));
wait.until(ExpectedConditions.elementToBeClickable(waitedElement));
// Clicking on the particular element using the JavaScriptExcecutor
((JavascriptExecutor) driver).executeScript("arguments[0].click();", waitedElement);
}
正如我之前提到的 JavaScriptExecutor,我也只在上述方法中包含了它的使用。
试试下面的端到端工作代码:
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import com.google.common.base.Function;
public class BasePage
{
// Declaring WebDriver
private static WebDriver driver;
private static void doClickUsingJSE(final WebElement element) {
// Using the Fluent Wait to avoid some exceptions like WebDriverException and StaleElementReferenceException
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(1, TimeUnit.MINUTES).pollingEvery(1, TimeUnit.SECONDS).ignoring(WebDriverException.class, StaleElementReferenceException.class);
WebElement waitedElement = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return element;
}
});
wait.until(ExpectedConditions.visibilityOf(waitedElement));
wait.until(ExpectedConditions.elementToBeClickable(waitedElement));
// Clicking on the particular element using the JavaScriptExcecutor
((JavascriptExecutor) driver).executeScript("arguments[0].click();", waitedElement);
}
public static void main( String[] args ) throws Exception
{
System.setProperty("webdriver.chrome.driver", "C:\\NotBackedUp\\chromedriver.exe");
// Initializing the Chrome Driver
driver = new ChromeDriver();
// Launching the LinkedIn site
driver.get("https://linkedin.com/search/results/people/?facetGeoRegion=[\"tr%3A0\"]&facetNetwork=[\"F\"]&origin=FACETED_SEARCH&page=YOUR_PAGE_NUMBER");
// You can avoid this and it to your convience way
// As there are no connections in my page, I have used like this
//------------------------------------------------------------------------------------
// Switching to the login from - iframe involved
driver.switchTo().frame(driver.findElement(By.className("authentication-iframe")));
// Clicking on the Sign In button
doClickUsingJSE(driver.findElement(By.xpath("//a[text()='Sign in']")));
// Entering the User Name
WebElement element = driver.findElement(By.id("username"));
doClickUsingJSE(element);
element.sendKeys("something@gmail.com");
// Entering the Password
element = driver.findElement(By.id("password"));
doClickUsingJSE(element);
element.sendKeys("anything"+Keys.ENTER);
// Clicking on the People drop down
Thread.sleep(8000);
element = driver.findElement(By.xpath("//span[text()='People']"));
doClickUsingJSE(element);
// Selecting the All option
Thread.sleep(2000);
element = driver.findElement(By.xpath("//ul[@class='list-style-none']/li[1]"));
element.click();
// Searching something in the LinkedIn search box
Thread.sleep(3000);
element = driver.findElement(By.xpath("//input[@role='combobox']"));
doClickUsingJSE(element);
element.sendKeys("a"+Keys.ENTER);
Thread.sleep(8000);
//------------------------------------------------------------------------------------
boolean next = true;
while(next) {
// Identifying the all the profile links
List<WebElement> totalProfileLinks = driver.findElements(By.xpath("//h3[contains(@class, 'search-results__total')]/parent::div/ul/li"));
// Looping for getting the profile link
for(int i=1;i<totalProfileLinks.size();i++) {
// Scrolling so that it will be visible
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", totalProfileLinks.get(i));
// Fetching the anchor node
final WebElement link = driver.findElement(By.xpath("(//h3[contains(@class, 'search-results__total')]/parent::div/ul/li//div[contains(@class, 'search-result__info')]//a)["+i+"]"));
// Avoiding the StaleElementReferenceException
new FluentWait<WebDriver>(driver).withTimeout(1, TimeUnit.MINUTES).pollingEvery(1, TimeUnit.SECONDS).ignoring(StaleElementReferenceException.class).until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver arg0) {
return link;
}
});
// Fetching and printing the link from anchor node
System.out.println(link.getAttribute("href").trim());
}
// Checking 'Next >' button is there or not in the page
List<WebElement> nextButton = driver.findElements(By.className("next"));
// If the 'Next >' button is there then clicking on it otherwise stopping the execution
if(nextButton.size() > 0) {
doClickUsingJSE(nextButton.get(0));
System.out.println("=> 'Next >' button is there and clicked on it...");
} else {
next = false;
System.out.println("=> 'Next >' button is NOT there so stopping the execution...");
}
Thread.sleep(1000);
}
}
}
希望对您有所帮助...快乐编码...