英文:
Drag rows in order in a table python selenium
问题
我有一个类似这样的HTML代码。
链接到HTML:
http://threedonthemap.s3-website.ap-south-1.amazonaws.com/
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Easy Drag and Drop HTML Table Rows With jQuery</title>
<!-- Bootstrap core CSS -->
<link href="https://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="https://getbootstrap.com/docs/4.0/examples/starter-template/starter-template.css" rel="stylesheet">
</head>
<body>
<main role="main" class="container">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Id</th>
<th>Jabcode</th>
</tr>
</thead>
<tbody>
<tr>
<td>01</td>
<td>E24.9</td>
</tr>
<tr>
<td>02</td>
<td>J92.9</td>
</tr>
<tr>
<td>03</td>
<td>A10.2</td>
</tr>
<tr>
<td>04</td>
<td>B10.2</td>
</tr>
<tr>
<td>05</td>
<td>C4.9</td>
</tr>
<tr>
<td>06</td>
<td>D10.11</td>
</tr>
<tr>
<td>07</td>
<td>F19.10</td>
</tr>
</tbody>
</table>
</main><!-- /.container -->
<!-- Bootstrap & Core Scripts -->
<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">
$('tbody').sortable();
</script>
</body>
</html>
目前,该页面在网页中具有特定的顺序。
我想根据我在Python程序中提供的参数更改网页中项目的顺序。
这是我的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', 'C4.9']
driver = webdriver.Chrome('/chromedrivernew')
driver.get("file:///datasets/demodragable/index.html")
for item in jab_code_order:
cell = driver.find_element_by_xpath("//tr[@class='ui-sortable-handle']//td[text()='" + item + "']")
print(cell.text)
source_element = driver.find_element_by_xpath("//tr[@class='ui-sortable-handle']//td[text()='" + item + "']")
dest_element = driver.find_element_by_xpath("//tr[@class='ui-sortable-handle']//td[text()='A10.2']")
ActionChains(driver).drag_and_drop(source_element, dest_element).perform()
time.sleep(2)
使用当前的代码,表格的顺序如下:
我希望表格的顺序如下:
是否有一种Pythonic的方法来做到这一点,而不是通过循环?
任何帮助将不胜感激!
英文:
I have a html like this
Link to html
http://threedonthemap.s3-website.ap-south-1.amazonaws.com/
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Easy Drag and Drop HTML Table Rows With jQuery</title>
<!-- Bootstrap core CSS -->
<link href="https://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="https://getbootstrap.com/docs/4.0/examples/starter-template/starter-template.css" rel="stylesheet">
</head>
<body>
<main role="main" class="container">
<table class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Id</th>
<th>Jabcode</th>
</tr>
</thead>
<tbody>
<tr>
<td>01</td>
<td>E24.9</td>
</tr>
<tr>
<td>02</td>
<td>J92.9</td>
</tr>
<tr>
<td>03</td>
<td>A10.2</td>
</tr>
<tr>
<td>04</td>
<td>B10.2</td>
</tr>
<tr>
<td>05</td>
<td>C4.9</td>
</tr>
<tr>
<td>06</td>
<td>D10.11</td>
</tr>
<tr>
<td>07</td>
<td>F19.10</td>
</tr>
</tbody>
</table>
</main><!-- /.container -->
<!-- Bootstrap & Core Scripts -->
<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">
$('tbody').sortable();
</script>
</body>
</html>
Which currently has the particular order in webpage
I want to change the order of the items in the webpage based on parameters I give in my python program.
Here 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','C4.9']
# browser =
driver = webdriver.Chrome('/chromedrivernew')
driver.get("file:////datasets/demodragable/index.html")
for item in jab_code_order:
cell=driver.find_element_by_xpath("//tr[@class='ui-sortable-handle']//td[text()='"+ item + "']")
print(cell.text)
source_element = driver.find_element_by_xpath("//tr[@class='ui-sortable-handle']//td[text()='"+ item + "']")
dest_element = driver.find_element_by_xpath("//tr[@class='ui-sortable-handle']//td[text()='A10.2']")
ActionChains(driver).drag_and_drop(source_element, dest_element).perform()
time.sleep(2)
With the current code it is coming like this
I want the table order like this
Is there any pythonic way of doing it rather than looping through ?
Any help would be appreciated !!
答案1
得分: 2
这里是翻译好的部分:
这是一个面试问题吗?哈哈,还有其他问题吗?
问题在于,此页面上的 drag_and_drop
只在所需目标位于源上方时才起作用。我使用了 drag_and_drop_by_offset
来解决这个问题,并添加了 5 个像素。请查看这里的文档(https://selenium.dev/selenium/docs/api/py/webdriver/selenium.webdriver.common.action_chains.html)。还要记住,每次移动一个元素时,列表的顺序都会改变。我添加了一个新函数,以在循环的每次迭代中找到该页面上的所有元素,以解决这个问题。请参考下面的代码:
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', 'C4.9']
driver = webdriver.Chrome('C:\\Path\\To\\chromedriver.exe')
driver.get("file://C:\\Path\\To\\index.html")
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]
if dest_element.location['y'] - source_element.location['y'] < 0:
ActionChains(driver).drag_and_drop_by_offset(source_element,
0,
dest_element.location['y'] - source_element.location['y'] - 5).perform()
else:
ActionChains(driver).drag_and_drop_by_offset(source_element,
0,
dest_element.location['y'] - source_element.location['y']).perform()
time.sleep(2)
希望对你有所帮助!
英文:
Is this an interview question lol? You got some more for me?
Here is the issue, drag_and_drop
on this page only works when your desired destination is below your source. I used drag_and_drop_by_offset
to fix this and add 5 pixels. See the documentation here (https://selenium.dev/selenium/docs/api/py/webdriver/selenium.webdriver.common.action_chains.html) Also remember that every time you move an element the order of the list has been changed. I added a new function to find all the elements on that page for each iteration of the loop to solve that issue.
See below:
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','C4.9']
# browser =
driver = webdriver.Chrome('C:\\Path\\To\\chromedriver.exe')
driver.get("file://C:\\Path\\To\\index.html")
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]
if dest_element.location['y'] - source_element.location['y'] < 0:
ActionChains(driver).drag_and_drop_by_offset(source_element,
0,
dest_element.location['y'] - source_element.location['y'] - 5).perform()
else:
ActionChains(driver).drag_and_drop_by_offset(source_element,
0,
dest_element.location['y'] - source_element.location['y']).perform()
time.sleep(2)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论