我正在使用 Java 17.0.7 和 Selenium 4.19.1。
首先,这是我编写的代码:
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class App {
public static void main(String[] args) {
Thread sessionOneThread = new Thread(() -> executeSession("Смартфон", "Session One"));
Thread sessionTwoThread = new Thread(() -> executeSession("Годинник", "Session Two"));
Thread sessionThreeThread = new Thread(() -> executeSession("Ноутбук", "Session Three"));
sessionOneThread.start();
sessionTwoThread.start();
sessionThreeThread.start();
}
public static void executeSession(String searchQuery, String sessionName) {
EdgeOptions options = new EdgeOptions();
options.addArguments("start-maximized", "--guest");
WebDriver driver = new EdgeDriver(options);
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
try {
driver.get("https://rozetka.com.ua/ua/");
WebElement searchInput =
wait.until(ExpectedConditions.elementToBeClickable
(By.cssSelector(".search-form__input")));
searchInput.sendKeys(searchQuery);
searchInput.sendKeys(Keys.ENTER);
List<WebElement> pageElements =
wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy
(By.cssSelector(".goods-tile__content")));
Map<String, String> pageMap = new LinkedHashMap<>();
for (WebElement element : pageElements) {
WebElement titleElement = element.findElement(By.cssSelector(".goods-tile__title"));
WebElement priceElement = element.findElement(By.cssSelector(".goods-tile__price-value"));
String title = titleElement.getText().trim();
String price = priceElement.getText().trim();
pageMap.put(title, price);
}
printResults(sessionName, pageMap);
} finally {
driver.manage().deleteAllCookies();
driver.quit();
}
}
public static void printResults(String sessionName, Map<String, String> data) {
System.out.println("Results for " + sessionName + ":");
for (Map.Entry<String, String> entry : data.entrySet()) {
System.out.println("Title: " + entry.getKey() + ", Price: " + entry.getValue());
}
System.out.println();
}
}
目标是打开三个并行线程,搜索特定项目并检索其标题和价格。非常简单。
现在的问题是有时它不起作用。有时会,有时不会。当它没有时 - 某些浏览器窗口会自动解析并关闭,而其他浏览器窗口似乎会加载页面,但没有任何内容被关闭或刮擦,而是我得到“没有这样的执行上下文”异常。我也可能会得到
StaleElementReferenceException
,特别是当两个线程同时失败时。我真的无法解决这个问题。
如果有人指出我的代码中的任何潜在问题,我将不胜感激,因为我发现自己无法自己解决它。
这是我的问题的视频演示:
--> YouTube 链接 <--
我运行了三遍。失败了两次,成功了一次。
没有这样的执行上下文异常错误日志:
Exception in thread "Thread-2" org.openqa.selenium.WebDriverException: no such execution context
(Session info: MicrosoftEdge=123.0.2420.65)
Build info: version: '4.19.1', revision: 'abe0ee07dc'
System info: os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.7'
Driver info: org.openqa.selenium.edge.EdgeDriver
Command: [0b4fb4bfddb7c01b95fa1290d7996f5f, clickElement {id=f.2047D5BB279D97BBA968AEA56212CFCD.d.21E45996CD2BC2E8365AADF4ECD43176.e.35}]
Capabilities {acceptInsecureCerts: false, browserName: MicrosoftEdge, browserVersion: 123.0.2420.65, fedcm:accounts: true, ms:edgeOptions: {debuggerAddress: localhost:58002}, msedge: {msedgedriverVersion: 123.0.2420.65 (49b6a5859239..., userDataDir: C:\Users\ENROUT~1\AppData\L...}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: windows, proxy: Proxy(), se:cdp: ws://localhost:58002/devtoo..., se:cdpVersion: 123.0.2420.65, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true}
Element: [[EdgeDriver: MicrosoftEdge on windows (0b4fb4bfddb7c01b95fa1290d7996f5f)] -> xpath: //button[contains(@class, 'search-form__submit')]]
Session ID: 0b4fb4bfddb7c01b95fa1290d7996f5f
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.openqa.selenium.remote.ErrorCodec.decode(ErrorCodec.java:167)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:138)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:50)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:190)
at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:216)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:174)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:518)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:223)
at org.openqa.selenium.remote.RemoteWebElement.click(RemoteWebElement.java:76)
at nltu.task11.App.searchAndRetrieveData(App.java:34)
at nltu.task11.App.executeSessionThree(App.java:81)
at java.base/java.lang.Thread.run(Thread.java:833)
StaleElementReferenceException错误日志:
Exception in thread "Thread-1" org.openqa.selenium.StaleElementReferenceException: stale element reference: stale element not found in the current frame
(Session info: MicrosoftEdge=123.0.2420.65)
For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception
Build info: version: '4.19.1', revision: 'abe0ee07dc'
System info: os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.7'
Driver info: org.openqa.selenium.edge.EdgeDriver
Command: [1361c295cd46263dc225417f2dbc8f08, getElementText {id=f.4CAC34CAB98D2D0552960E68DF18F862.d.53D0E5A121385BF7622766ADC3279883.e.182}]
Capabilities {acceptInsecureCerts: false, browserName: MicrosoftEdge, browserVersion: 123.0.2420.65, fedcm:accounts: true, ms:edgeOptions: {debuggerAddress: localhost:61353}, msedge: {msedgedriverVersion: 123.0.2420.65 (49b6a5859239..., userDataDir: C:\Users\ENROUT~1\AppData\L...}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: windows, proxy: Proxy(), se:cdp: ws://localhost:61353/devtoo..., se:cdpVersion: 123.0.2420.65, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true}
Element: [[[[EdgeDriver: MicrosoftEdge on windows (1361c295cd46263dc225417f2dbc8f08)] -> css selector: .goods-tile__content]] -> xpath: .//span[@class='goods-tile__price-value']]
Session ID: 1361c295cd46263dc225417f2dbc8f08
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.openqa.selenium.remote.ErrorCodec.decode(ErrorCodec.java:167)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:138)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:50)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:190)
at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:216)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:174)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:518)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:223)
at org.openqa.selenium.remote.RemoteWebElement.getText(RemoteWebElement.java:191)
at nltu.task11.App.searchAndRetrieveData(App.java:48)
at nltu.task11.App.executeSessionTwo(App.java:75)
at java.base/java.lang.Thread.run(Thread.java:833)
我试过:
我想我开始理解问题的根源。原因不在于代码,而在于网站本身。当我搜索某个项目时,它会加载页面,但随后会通过使用“特价”、“最佳价值”等内容更新这些项目来立即刷新文档对象模型。您可以在我提供的 YouTube 视频中清楚地看到发生的情况。
我尝试了不同的网上商店 - 它运行完美。现在我想知道我应该如何避免这个问题。比如,如果我不是逃避问题,而是必须找到解决方案并实际处理它,我该怎么办?我对网络测试的有限知识目前无法回答这个问题,所以我将不胜感激任何建议。