我正在用Java中的Selenium编写一个程序来抓取网站(我会共享网站,但你需要一个帐户,所以我认为这没有帮助(。我使用的是镀铬驱动程序。我一直在想办法点击";立即运行"按钮(下面的html代码片段(。Selenium抱怨按钮不可点击,尽管我明确地等待按钮可点击。
这是我的代码:
public String getReport() {
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id='QTF_AdminTab']/a")));
driver.get("theurl");
wait.until(ExpectedConditions.urlToBe("theurl"));
String oldtab = driver.getWindowHandle();
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[1]/div[2]/div/div[1]/div/div/div[1]/div[4]/button[@class='_widget-form-run mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary']/span")));
driver.findElement(By.xpath("/html/body/div[1]/div[2]/div/div[1]/div/div/div[1]/div[4]/button[@class='_widget-form-run mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary']/span")).click();
//... I don't think the rest is relevant since the above line (line 114 in the log) is the one causing the trouble
}
我的xpath上升到<span>因为log语句显示了一些带有"想要点击"的内容。如果从xpath中删除span
,则不会发生任何更改。
这是日志:
Starting ChromeDriver 83.0.4103.39 (ccbf011cb2d2b19b506d844400483861342c20cd-refs/branch-heads/4103@{#416}) on port 41202
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
Jul 10, 2020 5:36:00 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
Exception in thread "main" org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element <span class="mdl-button__ripple-container">...</span> is not
clickable at point (796, 183). Other element would receive the click: <span class="mdl-button__ripple-container">...</span>
(Session info: chrome=83.0.4103.116)
Build info: version: '4.0.0-alpha-6', revision: '5f43a29cfc'
System info: host: '______', ip: '_______', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.7'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 83.0.4103.116, chrome: {chromedriverVersion: 83.0.4103.39 (ccbf011cb2d2b..., userDataDir: C:Users______AppDataLoca...}, goog:chromeOptions: {debuggerAddress: localhost:56109}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true}
Session ID: e2b8ff1a23cd9b0932c00af2b1ffd2b5
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:196)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:129)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:53)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:160)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:582)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:316)
at org.openqa.selenium.remote.RemoteWebElement.click(RemoteWebElement.java:85)
at reliant.abusescanner.PCCclient.getReport(PCCclient.java:114)
at reliant.abusescanner.Main.main(Main.java:72)
这是按钮的html代码:
<div class="flex-actions">
<button class="_widget-form-run mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" data-upgraded=",MaterialButton,MaterialRipple">Run now<span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></button>
<!--<button class="_component-save mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--secondary" style="display:none">Save</button>-->
<button class="_component-saveAs mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--secondary" style="" data-upgraded=",MaterialButton,MaterialRipple">Save As<span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></button>
<!--<button class="_component-delete mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--secondary" disabled>Delete</button>-->
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--secondary configMenuBtn" id="demo-menu-lower-right" data-upgraded=",MaterialButton,MaterialRipple">
More Actions <i class="material-icons configMenuList">arrow_drop_down</i>
<span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></button>
<div class="mdl-menu__container is-upgraded"><div class="mdl-menu__outline mdl-menu--bottom-right"></div><ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events" for="demo-menu-lower-right" data-upgraded=",MaterialMenu,MaterialRipple">
<li class="mdl-menu__item _component-save mdl-js-ripple-effect" tabindex="-1" data-upgraded=",MaterialRipple" style="display: none;">Save<span class="mdl-menu__item-ripple-container"><span class="mdl-ripple"></span></span></li>
<li disabled="disabled" class="mdl-menu__item _component-delete mdl-js-ripple-effect" tabindex="-1" data-upgraded=",MaterialRipple">Delete<span class="mdl-menu__item-ripple-container"><span class="mdl-ripple"></span></span></li>
</ul></div>
</div>
这里有一段更大的html代码(包括上面的代码(,以防它能帮助您回答问题:
<div class="mdl-body">
<div class="onboarding-report-section">
Reduce the time it takes to setup and run a report.
<a href="#" class="_onboarding-report-setup-details">Click here to learn more</a>
</div>
<h1>24 Hour Summary Report</h1>
<div class="_form"><div class="_widget-root mdl-form">
<div class="_widget-section mdl-form-section">
<div class="_widget-fields"><div class="_form-field-save_config mdl-field saveConfigurationComponent">
<div class="mdl-field-input">
<div class="mdl-form-label flex-label">My saved settings</div>
<div class="_publishOverlayPlaceholder"></div>
<div class="_component-dropdown flex-dropdown"><span class="_catalyst-flyoutList-select dropdown-anchor-input " tabindex="0" style="width:300px;">
<span class="dropdown-legend"></span>
<span class="dropdown-label">
Unsaved
</span>
<i class="material-icons dropdown-arrow">arrow_drop_down</i>
</span></div>
<div class="flex-actions">
<button class="_widget-form-run mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--primary" data-upgraded=",MaterialButton,MaterialRipple">Run now<span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></button>
<!--<button class="_component-save mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--secondary" style="display:none">Save</button>-->
<button class="_component-saveAs mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--secondary" style="" data-upgraded=",MaterialButton,MaterialRipple">Save As<span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></button>
<!--<button class="_component-delete mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--secondary" disabled>Delete</button>-->
<button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--secondary configMenuBtn" id="demo-menu-lower-right" data-upgraded=",MaterialButton,MaterialRipple">
More Actions <i class="material-icons configMenuList">arrow_drop_down</i>
<span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></button>
<div class="mdl-menu__container is-upgraded"><div class="mdl-menu__outline mdl-menu--bottom-right"></div><ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events" for="demo-menu-lower-right" data-upgraded=",MaterialMenu,MaterialRipple">
<li class="mdl-menu__item _component-save mdl-js-ripple-effect" tabindex="-1" data-upgraded=",MaterialRipple" style="display: none;">Save<span class="mdl-menu__item-ripple-container"><span class="mdl-ripple"></span></span></li>
<li disabled="disabled" class="mdl-menu__item _component-delete mdl-js-ripple-effect" tabindex="-1" data-upgraded=",MaterialRipple">Delete<span class="mdl-menu__item-ripple-container"><span class="mdl-ripple"></span></span></li>
</ul></div>
</div>
</div>
<div class="_setting-instructions"></div>
<div class="_component-field-error mdl-field-errors"></div>
</div></div>
</div>
<div class="_widget-section mdl-form-section">
<div class="_widget-fields"><div class="_form-field-dateEnding mdl-field">
<div class="mdl-field-input datePickerComponent unSavedConfigField">
<div class="mdl-field-header">
<div class="mdl-form-label">Date (Ending)<span class="unSavedConfiglabelDisplay">(Date (Ending) won't be saved in the setting)</span></div>
</div>
<span class="_toggleRange" style="display: none;">From </span>
<input class="_fromDate catalyst-datepicker" style="margin-right:25px;">
<span class="_toggleRange" style="display: none;">
To <input class="_toDate catalyst-datepicker">
<input type="hidden" value="2020-07-10" name="end_date"></span>
<input type="hidden" value="2020-07-10" name="start_date"></div>
<div class="_component-field-error mdl-field-errors"></div>
</div><div class="_form-field-unit mdl-field">
<div class="mdl-field-input genericComponent">
<div class="mdl-field-header">
<div class="mdl-form-label">Unit</div>
</div>
<div class="_dropdown"><span class="_catalyst-flyoutList-select dropdown-anchor-input " tabindex="0" style="width:315px;">
<span class="dropdown-legend"></span>
<span class="dropdown-label">
All
</span>
<i class="material-icons dropdown-arrow">arrow_drop_down</i>
</span></div>
</div>
<div class="_component-field-error mdl-field-errors"></div>
</div><div class="_form-field-floor mdl-field">
<div class="mdl-field-input genericComponent">
<div class="mdl-field-header">
<div class="mdl-form-label">Floor</div>
</div>
<div class="_dropdown"><span class="_catalyst-flyoutList-select dropdown-anchor-input " tabindex="0" style="width:315px;">
<span class="dropdown-legend"></span>
<span class="dropdown-label">
All
</span>
<i class="material-icons dropdown-arrow">arrow_drop_down</i>
</span></div>
</div>
<div class="_component-field-error mdl-field-errors"></div>
</div><div class="_form-field-timeEnding mdl-field">
<div class="mdl-field-input hourMinuteTimeComponent">
<div class="mdl-field-header">
<div class="mdl-form-label">Ending Time</div>
</div>
<div class="_nestedContent">
<div class="_nestedHours"><span class="_catalyst-flyoutList-select dropdown-anchor-input " tabindex="0" style="width:50px;">
<span class="dropdown-legend"></span>
<span class="dropdown-label">
13
</span>
<i class="material-icons dropdown-arrow">arrow_drop_down</i>
</span></div>
<div class="_nestedMinutes"><span class="_catalyst-flyoutList-select dropdown-anchor-input " tabindex="0" style="width:50px;">
<span class="dropdown-legend"></span>
<span class="dropdown-label">
00
</span>
<i class="material-icons dropdown-arrow">arrow_drop_down</i>
</span></div>
</div>
</div>
<div class="_component-field-error mdl-field-errors"></div>
</div><div class="_form-field-summaryInterval mdl-field">
<div class="catalyst-field-input">
<div class="mdl-field-header">
<div class="mdl-form-label">Summary Interval</div>
</div>
<label class="_mdl-radio mdl-radio mdl-js-radio mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events is-upgraded" for="formObj_summaryInterval_8" data-upgraded=",MaterialRadio,MaterialRipple">
<input type="radio" class="mdl-radio__button" id="formObj_summaryInterval_8" name="summaryInterval" value="8">
<span class="mdl-radio__label">Last 8 hours</span>
<span class="mdl-radio__outer-circle"></span><span class="mdl-radio__inner-circle"></span><span class="mdl-radio__ripple-container mdl-js-ripple-effect mdl-ripple--center" data-upgraded=",MaterialRipple"><span class="mdl-ripple"></span></span></label>
<label class="_mdl-radio mdl-radio mdl-js-radio mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events is-upgraded is-checked" for="formObj_summaryInterval_24" data-upgraded=",MaterialRadio,MaterialRipple">
<input type="radio" class="mdl-radio__button" id="formObj_summaryInterval_24" name="summaryInterval" value="24">
<span class="mdl-radio__label">Last 24 hours</span>
<span class="mdl-radio__outer-circle"></span><span class="mdl-radio__inner-circle"></span><span class="mdl-radio__ripple-container mdl-js-ripple-effect mdl-ripple--center" data-upgraded=",MaterialRipple"><span class="mdl-ripple"></span></span></label>
<label class="_mdl-radio mdl-radio mdl-js-radio mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events is-upgraded" for="formObj_summaryInterval_72" data-upgraded=",MaterialRadio,MaterialRipple">
<input type="radio" class="mdl-radio__button" id="formObj_summaryInterval_72" name="summaryInterval" value="72">
<span class="mdl-radio__label">Last 72 hours</span>
<span class="mdl-radio__outer-circle"></span><span class="mdl-radio__inner-circle"></span><span class="mdl-radio__ripple-container mdl-js-ripple-effect mdl-ripple--center" data-upgraded=",MaterialRipple"><span class="mdl-ripple"></span></span></label>
</div>
<div class="_component-field-error mdl-field-errors"></div>
</div><div class="_form-field-includeDraftProgressNotes mdl-field">
<div class="catalyst-field-input">
<div class="mdl-field-header">
<div class="mdl-form-label">Include draft progress notes on report</div>
</div>
<label class="_mdl-radio mdl-radio mdl-js-radio mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events is-upgraded is-checked" for="formObj_includeDraftProgressNotes_true" data-upgraded=",MaterialRadio,MaterialRipple">
<input type="radio" class="mdl-radio__button" id="formObj_includeDraftProgressNotes_true" name="includeDraftProgressNotes" value="true">
<span class="mdl-radio__label">Yes</span>
<span class="mdl-radio__outer-circle"></span><span class="mdl-radio__inner-circle"></span><span class="mdl-radio__ripple-container mdl-js-ripple-effect mdl-ripple--center" data-upgraded=",MaterialRipple"><span class="mdl-ripple"></span></span></label>
<label class="_mdl-radio mdl-radio mdl-js-radio mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events is-upgraded" for="formObj_includeDraftProgressNotes_false" data-upgraded=",MaterialRadio,MaterialRipple">
<input type="radio" class="mdl-radio__button" id="formObj_includeDraftProgressNotes_false" name="includeDraftProgressNotes" value="false">
<span class="mdl-radio__label">No</span>
<span class="mdl-radio__outer-circle"></span><span class="mdl-radio__inner-circle"></span><span class="mdl-radio__ripple-container mdl-js-ripple-effect mdl-ripple--center" data-upgraded=",MaterialRipple"><span class="mdl-ripple"></span></span></label>
</div>
<div class="_component-field-error mdl-field-errors"></div>
</div><div class="_form-field-sortBy mdl-field">
<div class="catalyst-field-input">
<div class="mdl-field-header">
<div class="mdl-form-label">Sort Residents By</div>
</div>
<label class="_mdl-radio mdl-radio mdl-js-radio mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events is-upgraded" for="formObj_sortBy_-1" data-upgraded=",MaterialRadio,MaterialRipple">
<input type="radio" class="mdl-radio__button" id="formObj_sortBy_-1" name="sortBy" value="-1">
<span class="mdl-radio__label">Last Name</span>
<span class="mdl-radio__outer-circle"></span><span class="mdl-radio__inner-circle"></span><span class="mdl-radio__ripple-container mdl-js-ripple-effect mdl-ripple--center" data-upgraded=",MaterialRipple"><span class="mdl-ripple"></span></span></label>
<label class="_mdl-radio mdl-radio mdl-js-radio mdl-js-ripple-effect mdl-js-ripple-effect--ignore-events is-upgraded is-checked" for="formObj_sortBy_1" data-upgraded=",MaterialRadio,MaterialRipple">
<input type="radio" class="mdl-radio__button" id="formObj_sortBy_1" name="sortBy" value="1">
<span class="mdl-radio__label">Location</span>
<span class="mdl-radio__outer-circle"></span><span class="mdl-radio__inner-circle"></span><span class="mdl-radio__ripple-container mdl-js-ripple-effect mdl-ripple--center" data-upgraded=",MaterialRipple"><span class="mdl-ripple"></span></span></label>
</div>
<div class="_component-field-error mdl-field-errors"></div>
</div></div>
</div>
</div></div>
<div class="_meadcoSection"></div>
</div>
如果我能做些什么让这个问题更容易回答,请告诉我。提前谢谢!
编辑:我审查了一些个人信息(带有"____"(。希望没事
如果您查看elementToBeClickable(..)
方法,您将看到"可点击的";是指";可见和启用";。
您可以看到的消息意味着某些元素与您的目标元素重叠。更改XPath没有帮助。
这种情况经常发生,因为应用程序布局被设计为以特定的屏幕分辨率显示,但测试是以较小的分辨率运行的,因此元素会相互交叉。
p.S.-wait.until(..)
返回由条件定位的元素,因此无需再次查找。你可以做一些类似的事情:
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/blah blah"));
该方法将Web元素作为参数。
List cccc=driver.findElements(By.xpath("//div[包含(@id,'loadmask'(]"(;
这会检查某些JavaScriptWebElement的加载是否完成。它存储了错误所说的将接收到点击的所有元素。在我的情况下,消息带有loadmask。在您的电脑中,它将在<span class="mdl-button__ripple-container">
附近
boolean pageload = wait.until(ExpectedConditions.invisibilityOfAllElements(cccc));
检查列表元素cccc是否为不可见
if (pageload) {
wait.until(ExpectedConditions.elementToBeClickable(element));
}
//如果元素不可见,则等待参数中提供的元素可点击
故障排除步骤很少;
你可以在点击元素之前暂停你的dom(谷歌(,看看在你的特定情况下发生了什么。在我的案例中,罪魁祸首是这个元素加载掩码,它加载了一些JS,导致我的测试失败。所以我在点击之前暂停了dom,看看发生了什么。你可以试试这个,看看它是否有帮助。
你的情况可能与我的不同,但如果你参考这里,有很多方法可以实现预期条件
https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html
等待可能很棘手,只是为了使用thread.sleep(15000(进行故障排除,并查看元素是否可点击。有一次我出现了类似的错误-其他元素会收到点击:,这意味着页面仍在加载,我通过根据这个问题实现这两个方法解决了我的问题,然而,我总是可以通过使用thread.sleep(15000(在没有这些自定义方法的情况下点击元素,所以我建议首先尝试找出问题,以下是我的等待方法,
显示public void(WebElement元素({尝试{
WebDriverWait wait = new WebDriverWait(driver, 90);
List<WebElement> cccc = driver.findElements(By.xpath("//div[contains(@id,'loadmask')]"));
boolean pageload = wait.until(ExpectedConditions.invisibilityOfAllElements(cccc));
// boolean pageload=
// wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[contains(@id,'loadmask-')]")));
System.out.println(a);
if (pageload) {
wait.until(ExpectedConditions.elementToBeClickable(element));
}
} catch (org.openqa.selenium.NoSuchElementException exception) {
}
}
//第二种方法
public void elementwaitClick(WebElement waitForelement) {
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(waitForelement));
element.click();