【问题标题】:Drag by specific column sort the table python selenium按特定列拖动排序表python selenium
【发布时间】:2020-01-06 16:19:31
【问题描述】:

我有一个这样的 html

链接到 html

http://fileuploadios.s3-website-us-east-1.amazonaws.com/

<style type="text/css">
                body {
              font-size: 14px;
            }

            .drag-handler {
              width: 8em;
              position: relative;
              background-color: #E4E6EB;
              background-image: linear-gradient(45deg, #E4E6EB, #E4E6EB 2px, #fff 2px, #fff 4px, #E4E6EB 4px, #E4E6EB 9px, #fff 9px, #fff 11px, #E4E6EB 11px, #E4E6EB 16px, #fff 16px, #fff 18px, #E4E6EB 18px, #E4E6EB 22px);
              background-size: 10px 20px;
              cursor: move;
              border-top: 2px solid #FFF;
              border-bottom: 2px solid #FFF;
            }

            .drag-handler:active {
              background-image: linear-gradient(45deg, #bab86c, #bab86c 2px, #fff 2px, #fff 4px, #bab86c 4px, #bab86c 9px, #fff 9px, #fff 11px, #bab86c 11px, #bab86c 16px, #fff 16px, #fff 18px, #bab86c 18px, #bab86c 22px);
              background-size: 10px 20px;
            }

</style>
<table class="table table-hover table-striped">
  <thead>
    <tr>
      <th>
        Drag Button
      </th>
      <th>
        Number
      </th>
      <th>
        Jabcode
      </th>
    </tr>
  </thead>

  <tbody id="sortable">
    <tr>
      <td class="ui-state-default drag-handler" ></td>
      <td>1</td>
        <td>E24.9</td>
    </tr>
    <tr>
      <td class="ui-state-default drag-handler" ></td>
      <td>2</td>
              <td>J92.9</td>
    </tr>
    <tr>
      <td class="ui-state-default drag-handler" ></td>
      <td>3</td>
              <td>A10.2</td>
    </tr>
        <tr>
      <td class="ui-state-default drag-handler" ></td>
      <td>4</td>
              <td>B10.2</td>
    </tr>
        <tr>
      <td class="ui-state-default drag-handler" ></td>
      <td>5</td>
              <td>C4.9</td>
    </tr>
        <tr>
      <td class="ui-state-default drag-handler" ></td>
      <td>6</td>
              <td>D10.11</td>
    </tr>
        <tr>
      <td class="ui-state-default drag-handler" ></td>
      <td>7</td>
              <td>F19.10</td>             
    </tr>
        <tr>
      <td class="ui-state-default drag-handler" ></td>
      <td>8</td>
      <td>Z20.2</td>
    </tr>
  </tbody>
</table>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> 
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script> 
    <script src="https://getbootstrap.com/dist/js/bootstrap.min.js"></script>

<script type="text/javascript">
    $(document).ready(function() {

  $("#sortable").sortable({
    handle: ".drag-handler"
  });
  $("#sortable").disableSelection();

});

</script>

就是下面这种方式

我想根据我的 python 程序中的 Jabcode 重新排列它

jab_code_order =['J92.9','A10.2','E24.9','B10.2','F19.10','D10.11']

这是我的python代码

from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
import time 

jab_code_order =['J92.9','A10.2','E24.9','B10.2','F19.10','D10.11']
lis = ["1","2","3",]



driver = webdriver.Chrome('chromedrivernew')
driver.get("file:////newhtml.html")

time.sleep(5)


def get_current_element_order():
    array_of_elements = driver.find_elements_by_xpath("//tbody//tr")
    return array_of_elements

for item in range(len(jab_code_order)):
    cell=driver.find_element_by_xpath("//tr[@class='ui-sortable-handle']//td[text()='"+ jab_code_order[item] + "']")
    # print(cell.text)
    source_element = driver.find_element_by_xpath("//tr[@class='ui-sortable-handle']//td[text()='"+ jab_code_order[item] + "']")
    current_order_of_elements = get_current_element_order()
    dest_element = current_order_of_elements[item]
    # print(dest_element)
    # children = source_element.find_elements_by_xpath('./*')
    # print(children)


    if dest_element.location['y'] - source_element.location['y'] < 0:
        # print(dest_element.location['y'])
        print("if")
        print(source_element,0,dest_element.location['y'] - source_element.location['y'] - 1)

        ActionChains(driver).drag_and_drop_by_offset(source_element,
                                                     0,
                                                     dest_element.location['y'] - source_element.location['y'] - 5).perform()
    else:
        print("else")
        ActionChains(driver).drag_and_drop_by_offset(source_element,
                                                     0,
                                                     dest_element.location['y'] - source_element.location['y']).perform()
    time.sleep(2)

我想要这样的输出

但我当前的代码无法做到这一点,它会尝试进入 Jabcode 并尝试拖动。基于jabcode如何从tr中的第一个孩子拖动表格中的元素?

帮助将不胜感激! 谢谢+

【问题讨论】:

    标签: python python-3.x selenium selenium-webdriver


    【解决方案1】:

    因此,这里的挑战是找到一种方法,将按钮元素映射到具有变量 jab_code_order 中的文本的元素。

    我添加了一些“辅助函数”,它们每次都会执行以获取新列表的顺序。也许不是最“程序效率”但有效。

    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    import time
    driver = webdriver.Chrome(executable_path=r'C:\Path\\To\\chromedriver.exe')
    
    driver.get('file://C:\Path\\To\\newhtml.html')
    
    time.sleep(2)
    
    
    jab_code_order =['J92.9','A10.2','E24.9','B10.2','F19.10','D10.11']
    lis = ["1","2","3",]
    
    def get_current_element_order():
        array_of_elements = driver.find_elements_by_xpath("//tbody//tr")
        return array_of_elements
    
    def map_text_lcation():
        text_array_to_return = []
        for element in get_current_element_order():
            text_array_to_return.append(element.text)
        return text_array_to_return
    
    
    def get_current_button_order():
        get_current_button_order_dict = {}
        for iii in range(len(map_text_lcation())):
            for ii in get_current_element_order():
                a = driver.find_element_by_css_selector("tbody tr:nth-child({})".format(iii + 1))
                if ii.text == a.text:
                    get_current_button_order_dict[ii.text] = driver.find_element_by_css_selector("tbody tr:nth-child({}) td:nth-child(1)".format(iii + 1))
        return get_current_button_order_dict
    
    for item in range(len(jab_code_order)):
        element_dict = get_current_button_order()
        this_key = ""
        for key in element_dict:
            if jab_code_order[item] in key:
                this_key = key
        source_element = element_dict[this_key]
        current_order_of_elements = get_current_element_order()
        dest_element = current_order_of_elements[item]
    
        if dest_element.location['y'] - source_element.location['y'] < 0:
            print("if")
            print(source_element,0,dest_element.location['y'] - source_element.location['y'] - 1)
    
            ActionChains(driver).drag_and_drop_by_offset(source_element,
                                                         0,
                                                         dest_element.location['y'] - source_element.location['y'] - 5).perform()
        else:
            print("else")
            ActionChains(driver).drag_and_drop_by_offset(source_element,
                                                         0,
                                                         dest_element.location['y'] - source_element.location['y']).perform()
        WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"tbody tr:nth-child(1) td:nth-child(1)")))
    

    【讨论】:

    • 很好的答案。也许用 WebDriverWait 替换 time.sleep(2) 会使其完美无缺。
    猜你喜欢
    • 2020-04-22
    • 2020-05-28
    • 2020-02-23
    • 2017-04-08
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多