【问题标题】:Selenium selecting first row in a table even though I'm iterating through the rowsSelenium 选择表中的第一行,即使我正在遍历行
【发布时间】:2020-05-20 05:09:24
【问题描述】:

我真的不确定这里发生了什么,也无法弄清楚,所以希望有人可以帮助我。

基本上,我是在选择一个表,然后查找该表中的所有行。从这里,我遍历行并选择三个复选框并检查它们是否被选中。但是,我为每一行得到的结果总是第一行。例如

错误 真的 假的

那么……

错误 真的 假的

何时应该更改每一行。

Python/Selenium 代码:​​

table = driver.find_element_by_xpath("//table[@id='tableMscRatesModal']/tbody")
rows = table.find_elements(By.XPATH, "//tr[@class='ng-scope']") # get all of the rows in the tables

for row in rows:
    print(row.text)

    manager_box = row.find_element_by_xpath("//td/input[@type='radio'][contains(@name, 'userRole')][@value='1']")
    standard_box = row.find_element_by_xpath("//td/input[@type='radio'][contains(@name, 'userRole')][@value='2']")
    no_box = row.find_element_by_xpath("//td/input[@type='radio'][contains(@name, 'userRole')][@value='3']")

    print(manager_box.is_selected())
    print(standard_box.is_selected())
    print(no_box.is_selected())

    if not (manager_box.is_selected() or standard_box.is_selected() or no_box.is_selected()):
        standard_box.send_keys(Keys.SPACE)

我在下面包含了两行的示例。这对 x 行重复完全相同。

HTML:

<table id="tableMscRatesModal" ng-table="tableParams" class="table table-striped table-bordered" show-filter="false">
    <colgroup>
        <col span="1" style="width: 13%;">
            <col span="1" style="width: 13%;">
                <col span="1" style="width: 8%;">
                    <col span="1" style="width: 8%;">
                        <col span="1" style="width: 8%;">
                            <col span="1" style="width: 25%;">
                                <col span="1" style="width: 25%;">
    </colgroup>
    <tbody>
        <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Manager</th>
            <th>Standard user</th>
            <th>No access</th>
            <th>Proposed change</th>
            <th ng-show="iAmRequestManagerWithProposals(getUserList())" class="ng-hide">
                Approval
                <br>
                <br>
                <div class="row approvals">
                    <div class="col-xs-12">
                        <div class="input-group">
                            <span class="input-group-addon">
                                <label ng-click="rejectAll()">
                                    <input type="radio" name="rejectapproveall" id="rejectall" value="rejectall">
                                    Reject all
                                </label>
                            </span>
                            <span class="input-group-addon">
                                <label ng-click="approveAll()">
                                    <input type="radio" name="rejectapproveall" id="acceptall" value="acceptall">
                                    Approve all
                                </label>
                            </span>
                        </div>
                    </div>
                </div>
            </th>
        </tr>
        <!-- ngRepeat: accessUser in manageAccessControl.usersAndRoles | orderBy:['sortOrder','lastName','firstName'] -->
        <tr ng-repeat="accessUser in manageAccessControl.usersAndRoles | orderBy:['sortOrder','lastName','firstName']" class="ng-scope">
            <td class="ng-binding">First Name</td>
            <td class="ng-binding">Last Name</td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.manager" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="1">
            </td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.stdUser" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="2">
            </td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.noAccess" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="3">
            </td>
            <td>
                <span ng-show="accessUser.proposedRoleId" class="ng-hide">
                    <img tooltip-placement="left" tooltip-append-to-body="true" uib-tooltip-html="getRoleChangeProposal(accessUser)" src="/img/infoIcon.png" style="width: 12px; height: 12px">
                    Pending manager approval
                </span>
                <span ng-show="accessUser.isAmsAdmin" class="ng-hide">
                    <img tooltip-placement="left" tooltip-append-to-body="true" uib-tooltip-html="amsAdminUserTooltip" src="/img/infoIcon.png" style="width: 12px; height: 12px">
                    AMS admin user
                </span>
            </td>
            <td ng-show="iAmRequestManagerWithProposals(getUserList())" class="ng-hide">

                <div class="row approvals">
                    <div class="col-xs-12">
                        <div class="input-group ng-hide" ng-show="accessUser.proposedRoleId &amp;&amp; accessUser.proposedRoleId > 0">
                            <span class="input-group-addon">
                                <label ng-click="setApprovalForUser(accessUser, hmwAccess.rejectApprove.rejected)">
                                    <input type="radio" name="rejectapprove" id="reject" value="rejected" ng-model="accessUser.rejectApprove" class="ng-pristine ng-untouched ng-valid ng-empty">
                                    Reject
                                </label>
                            </span>
                            <span class="input-group-addon">
                                <label ng-click="setApprovalForUser(accessUser, hmwAccess.rejectApprove.approved)">
                                    <input type="radio" name="rejectapprove" id="accept" value="approved" ng-model="accessUser.rejectApprove" class="ng-pristine ng-untouched ng-valid ng-empty">
                                    Approve
                                </label>
                            </span>
                        </div>
                    </div>
                </div>

            </td>
        </tr>
        <!-- end ngRepeat: accessUser in manageAccessControl.usersAndRoles | orderBy:['sortOrder','lastName','firstName'] -->
        <tr ng-repeat="accessUser in manageAccessControl.usersAndRoles | orderBy:['sortOrder','lastName','firstName']" class="ng-scope">
            <td class="ng-binding">First Name</td>
            <td class="ng-binding">Last Name</td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.manager" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="1">
            </td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.stdUser" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="2">
            </td>
            <td>
                <input type="radio" name="userRole" ng-value="hmwAccess.roles.noAccess" ng-model="accessUser.selectedRoleId" ng-disabled="accessUser.proposedRoleId || accessUser.isAmsAdmin" class="ng-pristine ng-untouched ng-valid ng-not-empty" value="3">
            </td>
            <td>
                <span ng-show="accessUser.proposedRoleId" class="ng-hide">
                    <img tooltip-placement="left" tooltip-append-to-body="true" uib-tooltip-html="getRoleChangeProposal(accessUser)" src="/img/infoIcon.png" style="width: 12px; height: 12px">
                    Pending manager approval
                </span>
                <span ng-show="accessUser.isAmsAdmin" class="ng-hide">
                    <img tooltip-placement="left" tooltip-append-to-body="true" uib-tooltip-html="amsAdminUserTooltip" src="/img/infoIcon.png" style="width: 12px; height: 12px">
                    AMS admin user
                </span>
            </td>
            <td ng-show="iAmRequestManagerWithProposals(getUserList())" class="ng-hide">

                <div class="row approvals">
                    <div class="col-xs-12">
                        <div class="input-group ng-hide" ng-show="accessUser.proposedRoleId &amp;&amp; accessUser.proposedRoleId > 0">
                            <span class="input-group-addon">
                                <label ng-click="setApprovalForUser(accessUser, hmwAccess.rejectApprove.rejected)">
                                    <input type="radio" name="rejectapprove" id="reject" value="rejected" ng-model="accessUser.rejectApprove" class="ng-pristine ng-untouched ng-valid ng-empty">
                                    Reject
                                </label>
                            </span>
                            <span class="input-group-addon">
                                <label ng-click="setApprovalForUser(accessUser, hmwAccess.rejectApprove.approved)">
                                    <input type="radio" name="rejectapprove" id="accept" value="approved" ng-model="accessUser.rejectApprove" class="ng-pristine ng-untouched ng-valid ng-empty">
                                    Approve
                                </label>
                            </span>
                        </div>
                    </div>
                </div>

            </td>
        </tr>

提前致谢!

【问题讨论】:

  • 那是单选按钮而不是复选框。但是你不能一次选择所有单选按钮。适用于复选框一次选择所有复选框。一次只能选择一个单选按钮。

标签: python python-3.x selenium xpath selenium-chromedriver


【解决方案1】:

当使用xpath从另一个元素中定位一个元素时,您需要使用当前上下文.

for row in rows:
    manager_box = row.find_element_by_xpath(".//td/input[@type='radio'][contains(@name, 'userRole')][@value='1']")
    standard_box = row.find_element_by_xpath(".//td/input[@type='radio'][contains(@name, 'userRole')][@value='2']")
    no_box = row.find_element_by_xpath(".//td/input[@type='radio'][contains(@name, 'userRole')][@value='3']")

如果你使用列表,你也可以简化你的代码

checkboxes = row.find_elements_by_xpath(".//td/input[@type='radio'][contains(@name, 'userRole')]")
for checkbox in checkboxes:
    print(checkboxes.is_selected())

如果你放弃print(row),甚至更远

checkboxes = row.find_elements_by_xpath("//table[@id='tableMscRatesModal']/tbody//tr[@class='ng-scope']//td/input[@type='radio']")
for i in range(0, len(checkboxes), 3):
    print(checkboxes[i].is_selected())
    print(checkboxes[i + 1].is_selected())
    print(checkboxes[i + 2].is_selected())

【讨论】:

  • 就是这样。现在似乎很简单,但我永远不会发现它。非常感谢您的帮助。
  • 你有没有问过自己为什么你永远不会发现它?是不是您在不理解它们的含义的情况下使用了语言中的结构(如“//”)?在开始编码之前,您是否可以通过阅读更多内容为自己节省大量时间?
猜你喜欢
  • 2020-09-22
  • 2016-06-05
  • 2018-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
相关资源
最近更新 更多