用Python和Selenium拖动特定列来排序表格。

huangapple go评论161阅读模式
英文:

Drag by specific column sort the table python selenium

问题

你的目标是使用Python程序根据Jabcode重新排列HTML表格中的元素,但你的当前代码似乎无法实现这一目标。你想知道如何根据Jabcode正确拖动表格中的元素。以下是可能有助于你的指导:

首先,你可以按照以下步骤来调整你的代码:

  1. 获取当前表格的所有行元素,可以使用driver.find_elements_by_xpath("//tbody//tr")来获取。
  2. 遍历jab_code_order列表,以确定每个Jabcode在表格中的位置。
  3. 找到每个Jabcode对应的源元素和目标元素。
  4. 使用ActionChains来拖动源元素到目标元素的位置。

在你的代码中,你可以尝试修改以下部分:

for item in range(len(jab_code_order)):
    # 找到源元素
    source_element = driver.find_element_by_xpath("//td[text()='" + jab_code_order[item] + "']")
    # 获取当前元素的顺序
    current_order_of_elements = get_current_element_order()
    # 找到目标元素
    dest_element = current_order_of_elements[item]
    
    # 根据目标元素的位置来确定拖动的距离
    offset_y = dest_element.location['y'] - source_element.location['y']
    
    # 使用ActionChains拖动元素
    ActionChains(driver).drag_and_drop_by_offset(source_element, 0, offset_y).perform()
    
    time.sleep(2)

这段代码应该根据Jabcode正确拖动表格中的元素,并产生你所期望的输出。希望这可以帮助你解决问题!如果你有任何其他问题,可以随时提问。

英文:

I have a html like this

Link to 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>

Which is in the following Way

用Python和Selenium拖动特定列来排序表格。

I want to rearrange this based on the Jabcode in my python program

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

This is my python code

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)

I want output like this

用Python和Selenium拖动特定列来排序表格。

But my current code fails to do that it tries to go the Jabcode and tries to drag. Based on the jabcode how to drag the element in the table from the first child in the tr ?

Help would be appreciated !!
Thanks+

答案1

得分: 2

这里的挑战是找到一种将按钮元素映射到变量 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

# 设置 Chrome 驱动程序路径
driver = webdriver.Chrome(executable_path=r'C:\Path\\To\\chromedriver.exe')

# 打开网页
driver.get('file://C:\Path\\To\\newhtml.html')

# 等待2秒
time.sleep(2)

# 定义变量 jab_code_order 和 lis
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_location():
    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_location())):
        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

# 遍历 jab_code_order 列表
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)")))
英文:

So the challenge here is finding a way to map the button element to the element with the text found in the variable jab_code_order.

I added a few "helper functions" that execute each time to get the order of the new list. Maybe not the most "programmiclly efficient" but works.

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&#39;C:\Path\\To\\chromedriver.exe&#39;)
driver.get(&#39;file://C:\Path\\To\\newhtml.html&#39;)
time.sleep(2)
jab_code_order =[&#39;J92.9&#39;,&#39;A10.2&#39;,&#39;E24.9&#39;,&#39;B10.2&#39;,&#39;F19.10&#39;,&#39;D10.11&#39;]
lis = [&quot;1&quot;,&quot;2&quot;,&quot;3&quot;,]
def get_current_element_order():
array_of_elements = driver.find_elements_by_xpath(&quot;//tbody//tr&quot;)
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(&quot;tbody tr:nth-child({})&quot;.format(iii + 1))
if ii.text == a.text:
get_current_button_order_dict[ii.text] = driver.find_element_by_css_selector(&quot;tbody tr:nth-child({}) td:nth-child(1)&quot;.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 = &quot;&quot;
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[&#39;y&#39;] - source_element.location[&#39;y&#39;] &lt; 0:
print(&quot;if&quot;)
print(source_element,0,dest_element.location[&#39;y&#39;] - source_element.location[&#39;y&#39;] - 1)
ActionChains(driver).drag_and_drop_by_offset(source_element,
0,
dest_element.location[&#39;y&#39;] - source_element.location[&#39;y&#39;] - 5).perform()
else:
print(&quot;else&quot;)
ActionChains(driver).drag_and_drop_by_offset(source_element,
0,
dest_element.location[&#39;y&#39;] - source_element.location[&#39;y&#39;]).perform()
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR,&quot;tbody tr:nth-child(1) td:nth-child(1)&quot;)))

huangapple
  • 本文由 发表于 2020年1月7日 00:19:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/59615492.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定