-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathseleniumfunc.py
More file actions
353 lines (311 loc) · 13.2 KB
/
Copy pathseleniumfunc.py
File metadata and controls
353 lines (311 loc) · 13.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : seleniumfunc.py
# @Author: shijiu
# @Date : 2020/8/7
# @SoftWare : PyCharm
import time
import json
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
class WebDriver():
def __init__(self):
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('chromedriver.exe')
self.browser = webdriver.Chrome(chrome_options=chrome_options)
self.browser.maximize_window()
self.browser.implicitly_wait(3)
self.get_iframe()
self.step_list = []
self.run_num = 0
# 加载页面
def get_url(self,url):
try:self.browser.get(url); return True
except: return False
# 获取当前网址
def get_current_url(self): return self.browser.current_url
# 隐式等待
def is_wait(self, xpath):
WebDriverWait(self.browser, 3000).until(lambda the_driver: the_driver.find_element_by_xpath(xpath).is_displayed())
def is_sleep(self):
time.sleep(3)
# 获取页面iframe ,自定义id,返回ID列表 。存表数据 指定iframe 的id
def get_iframe(self):
iframe = """
var arr1 = []
var iframes1= document.getElementsByTagName("iframe");
var iframes2= document.getElementsByTagName("frame");
for(var i=0;i<iframes1.length;i++) {
iframes1[i].style.overflow = "visible";
iframes1[i].setAttribute("id", "iframe1"+ i);
arr1.push(iframes1[i].id)
}
for(var i=0;i<iframes2.length;i++) {
iframes2[i].style.overflow = "visible";
iframes2[i].setAttribute("id", "iframe2"+ i);
arr1.push(iframes2[i].id)
}
return arr1
"""
iframe_id_list = self.browser.execute_script(iframe)
iframe_id_list.append("主界面")
return iframe_id_list
# 检查页面元素id是否存在
def test_id_Valid(self, name):
try:self.browser.find_element_by_id(name); self.browser.execute_script("window.stop()"); return True
except:return False
# 检查页面元素Class是否存在
def test_class_Valid(self, name):
try: e = self.browser.find_elements_by_class_name(name); self.browser.execute_script("window.stop()"); return len(e) > 0
except: return False
def check_id_exist(self,xpath):
try:
element = self.browser.find_element_by_xpath(xpath)
e_id = element.get_attribute('id')
return e_id
except:
return False
# 跳转到指定容器,需要参数 容器xpath。 type: jump
def switch_win(self, frame):
try:
if frame == "主界面":
self.browser.switch_to.default_content()
else:
iframe = self.browser.find_element_by_xpath(frame)
self.browser.switch_to.frame(iframe)
# 将跳转步骤插入入数据库
# sql = "SELECT * FROM [actionList] WHERE actionid = '%s';" % action_id
# sql = "INSERT INTO [actionList] (actionid,fatherid,actionType,xpath,remark) VALUES ('%s', '%s', '%s', '%s', '%s')" %()
# info = self.odb.ExecQuery(sql)
return True
except: return False
# 写入数据 find and input
def input_any(self, xpath, anything):
try:
inp = self.browser.find_element_by_xpath(xpath)
inp.send_keys(anything)
return True
except:return False
# 找到元素,返回元素 find
def find_ele(self, xpath):
try:
ele = self.browser.find_element_by_xpath(xpath)
return ele
except: return False
# 按钮、超链 点击 click
def click_in(self, xpath):
try: self.browser.find_element_by_xpath(xpath).click(); return True
except:return False
# 通过class 获取元素text
def judge_text(self, xpath):
try:
etext = self.browser.find_element_by_class_name(xpath).text
return etext
except: return False
# 初始化iframe id ,并把获取xpath的js注入到每个容器中。
def init_iframe(self):
self.browser.switch_to.default_content()
init_iframe = """
var arr1 = []
var iframes1= document.getElementsByTagName("iframe");
var iframes2= document.getElementsByTagName("frame");
for(var i=0;i<iframes1.length;i++) {
iframes1[i].style.overflow = "visible";
iframes1[i].setAttribute("id", "iframe1"+ i);
arr1.push(iframes1[i].id)
}
for(var i=0;i<iframes2.length;i++) {
iframes2[i].style.overflow = "visible";
iframes2[i].setAttribute("id", "iframe2"+ i);
arr1.push(iframes2[i].id)
}
return arr1
"""
iframe_id_list = self.browser.execute_script(init_iframe)
print(iframe_id_list)
self.get_xpath()
for iframe in iframe_id_list:
self.browser.switch_to.frame(iframe)
self.get_xpath()
self.browser.switch_to.default_content()
# 返回原来的iframe
# 注入获取目标元素xpath的js
def get_xpath(self):
js = """
var arr = [];
var result = []
var textarea = document.createElement("textarea");
textarea.setAttribute("id", "textarea_result");
document.body.appendChild(textarea);
var tags = document.getElementsByTagName('*')
var text11 = document.getElementById('textarea_result');
var tips = document.createElement("p");
tips.setAttribute("id", "tips_result");
tips.setAttribute("title", "tips_result");
document.body.appendChild(tips);
tips.style.position = "absolute";
tips.style.backgroundColor="yellow"
tips.style.zIndex = "999"
tips.style.display = "none"
tips.style.width = "500px"
tips.style.height = "50px"
tips.style.border = "black 1px solid"
console.log(text11)
console.log(tags)
for (var i = 0; i < tags.length; i++) {
if (tags[i].tagName === "HTML" || tags[i].tagName === "SCRIPT" || tags[i].tagName === "SCRIPT" || tags[i].tagName === "STYLE") {
continue
} else {
arr.push(tags[i])
}
}
var elementList = arr
// 给元素添加事件
var getXpath = function (element) {
//这里需要需要主要字符串转译问题,可参考js 动态生成html时字符串和变量转译(注意引号的作用)
if (element === document.body) {//递归到body处,结束递归
xPath = '/html/' + element.tagName.toLowerCase()
return xPath;
}
let ix = 1;//
let siblings = element.parentNode.childNodes;//ͬ
for (let i = 0, l = siblings.length; i < l; i++) {
let sibling = siblings[i];
if (sibling == element) {
return getXpath(element.parentNode) + '/' + element.tagName.toLowerCase() + '[' + (ix) + ']';
} else if (sibling.nodeType == 1 && sibling.tagName == element.tagName) {
ix++;
}
}
}
for (var i = 0; i < elementList.length; i++) {
let element = elementList[i]
const res = {xPath:"",content:""}
elementList[i].onmouseover = function (event) {
event.stopPropagation()
element.style.border = "1px solid blue"
var xPath ;
toRun = setTimeout(function () {
console.log(element)
res.content = ""
if (element.tagName == "INPUT" || element.tagName == "TEXTAREA"){
res.content = element.value
}else {
res.content = element.innerText
}
res.xPath = getXpath(element)
result.push(res)
console.log(JSON.stringify(result))
text11.value = JSON.stringify(result);
element.title = JSON.stringify(res);
tips.innerText = JSON.stringify(res)
var x = event.clientX + document.body.scrollLeft + 20;
var y = event.clientY + document.body.scrollTop - 5;
tips.style.left = x + "px";
tips.style.top = y + "px";
tips.style.display = "block";
return result
}, 3000)
element.style.border = "1px solid blue"
console.log("移入")
}
elementList[i].onmouseout = function (event) {
clearTime = clearTimeout(toRun)
tips.style.display = "none";
console.log("移出")
element.style.border = "1px solid rgba(0,0,0,0)"
}
}
"""
self.browser.execute_script(js)
# 获取采集到的xpath
def clear_list(self):
self.step_list.clear()
def get_active_element(self):
element = self.browser.switch_to.active_element
print(element)
if element: return element
return False
def get_current_window(self):
try:
window = self.browser.current_window_handle
return window
except:
return False
def get_all_windows(self):
try:
windows = self.browser.window_handles
return windows
except:
return False
def switch_to_window(self, index):
try:
self.browser.switch_to.window(self.browser.window_handles[index])
return True
except:
return False
# 每次采集xpath值前进行所在容器判断。判断后生成步骤。
def catch_xpath(self):
step_info = {'stepNumber': 1, 'actionType': '', 'url': '', 'xpath': '', 'value': '', 'remark': ''}
result_js = """
var xpathResult = document.getElementById('textarea_result');
console.log(xpathResult)
var result = xpathResult.value
xpathResult.value = ""
return result
"""
result = self.browser.execute_script(result_js)
# 如果是空,那么表示采集的数据不在这个容器内(或者用户没有选择目标元素),
if result == '':
self.browser.switch_to.default_content()
step_info['actionType'] = 'jump'
step_info['xpath'] = '主界面'
step_info['remark'] = '检测到目标元素不处于当前容器,跳转到目标容器,并新增跳转步骤。'
self.step_list.append(step_info)
self.run_num += 1
# 如果连续result为空,则表示用户没有选择目标元素 。跳出循环,提醒用户选择目标元素后继续。
if self.run_num > 1:
self.run_num = 0
print("未选择目标元素", self.step_list)
return self.step_list
return self.catch_xpath()
result = json.loads(result)
step_info['xpath'] = result[-1]['xPath']
# 查询xpath是否能找到元素。
if self.find_ele(result[-1]['xPath']) is False:
self.browser.switch_to.default_content()
if 'frame' in result[-1]['xPath']:
# 如果跳转成功,要将跳转步骤插入数据库中。该步骤会展示给录制用户
if self.switch_win(result[-1]['xPath']):
# 插入数据
# sql = "INSERT INTO [actionList] (actionid,fatherid,actionType,xpath,remark) VALUES ('%s', '%s', '%s', '%s', '%s')" %()
# info = self.odb.ExecQuery(sql)
step_info['actionType'] = 'jump'
step_info['remark'] = '检测到目标元素不处于当前容器,跳转到目标容器,并新增跳转步骤。'
self.step_list.append(step_info)
return self.catch_xpath()
else:
self.step_list.append(step_info)
return self.step_list
# 通过xpath给元素设置属性
def set_element_attribute(self, info):
js = """
var ele = document.evaluate('{}',document).iterateNext();
console.log(ele);
if(ele) {{
ele.setAttribute('{}','{}');
return true
}};
return false
""".format(info['xpath'], info['name'], info['value'])
done = self.browser.execute_script(js)
if done: return info
else:return done
# 通过id给标签画框
def add_style_border(self,id):
js = """document.getElementById('{}').style.border="3px solid red";""".format(id)
self.browser.execute_script(js)
# 通过id移除添加的样式
def remove_style(self,id):
js = """document.getElementById('{}').style="";""".format(id)
self.browser.execute_script(js)