瀏覽代碼

New click way

naibo 2 年之前
父節點
當前提交
04442a13fe

+ 1 - 1
.temp_to_pub/EasySpider_windows_x64/config.json

@@ -1 +1 @@
-{"webserver_address":"http://localhost","webserver_port":8074,"user_data_folder":"./user_data","absolute_user_data_folder":"D:\\Documents\\Projects\\EasySpider\\Releases\\EasySpider_windows_amd64\\user_data2"}
+{"webserver_address":"http://localhost","webserver_port":8074,"user_data_folder":"./user_data","absolute_user_data_folder":"D:\\Documents\\Projects\\EasySpider\\.temp_to_pub\\EasySpider_windows_x64\\user_data"}

文件差異過大導致無法顯示
+ 0 - 0
.temp_to_pub/EasySpider_windows_x64/execution_instances/27.json


文件差異過大導致無法顯示
+ 0 - 0
.temp_to_pub/EasySpider_windows_x64/execution_instances/28.json


文件差異過大導致無法顯示
+ 0 - 0
.temp_to_pub/EasySpider_windows_x64/execution_instances/29.json


文件差異過大導致無法顯示
+ 0 - 0
.temp_to_pub/EasySpider_windows_x64/execution_instances/30.json


文件差異過大導致無法顯示
+ 0 - 0
.temp_to_pub/EasySpider_windows_x64/execution_instances/31.json


文件差異過大導致無法顯示
+ 0 - 0
.temp_to_pub/EasySpider_windows_x64/execution_instances/32.json


文件差異過大導致無法顯示
+ 0 - 0
.temp_to_pub/EasySpider_windows_x64/execution_instances/33.json


文件差異過大導致無法顯示
+ 0 - 0
.temp_to_pub/EasySpider_windows_x64/tasks/46.json


二進制
ElectronJS/EasySpider_en.crx


二進制
ElectronJS/EasySpider_zh.crx


+ 1 - 1
ElectronJS/config.json

@@ -1 +1 @@
-{"webserver_address":"http://localhost","webserver_port":8074,"user_data_folder":"./user_data","absolute_user_data_folder":"/home/naibo/Documents/EasySpider/ElectronJS/user_data"}
+{"webserver_address":"http://localhost","webserver_port":8074,"user_data_folder":"./user_data","absolute_user_data_folder":"D:\\Documents\\Projects\\EasySpider\\ElectronJS\\user_data"}

+ 29 - 4
ElectronJS/main.js

@@ -186,10 +186,35 @@ async function beginInvoke(msg, ws) {
                 let message = JSON.parse(msg.message.pipe);
                 let type = message.type;
                 console.log("FROM Browser: ", message);
-                // if(type.indexOf("Click")>=0){
-                //     await new Promise(resolve => setTimeout(resolve, 2000)); //等两秒
-                //
-                // }
+                if(type.indexOf("Click")>=0){
+                    let handles = await driver.getAllWindowHandles();
+                    console.log("handles", handles);
+                    let exit = false;
+                    let content_handle = handle_pairs[message.id];
+                    console.log(message.id,  content_handle);
+                    let order = [...handles.filter(handle => handle != current_handle && handle != content_handle), current_handle, content_handle]; //搜索顺序
+                    let len = order.length;
+                    while(true) {
+                        try{
+                            let h = order[len - 1];
+                            console.log("current_handle", current_handle);
+                            if(h != null && handles.includes(h)){
+                                await driver.switchTo().window(h);
+                                current_handle = h;
+                                console.log("switch to handle: ", h);
+                            }
+                            let element = await driver.findElement(By.xpath(message.xpath));
+                            await element.click();
+                            break;
+                        } catch (error) {
+                            console.log("len", len);
+                            len = len - 1;
+                            if (len == 0) {
+                                break;
+                            }
+                        }
+                    }
+                }
             } else {
                 socket_window.send(msg.message.pipe);
                 console.log("FROM Flowchart: ", JSON.parse(msg.message.pipe));

+ 6 - 1
ElectronJS/src/taskGrid/FlowChart.html

@@ -129,6 +129,11 @@
                     </div>
                     <label>Maximum wait time for page load after clicking (in seconds):</label>
                     <input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['maxWaitTime']" type="number" required></input>
+                    <label>Click Type:</label>
+                    <select v-model='nowNode["parameters"]["clickWay"]' class="form-control">
+                        <option :value = 0>Selenium</option>
+                        <option :value = 1>JavaScript</option>
+                    </select>
                     <label>Whether to scroll down after clicking:</label>
                     <select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
                         <option value = 0>No Scrolling</option>
@@ -194,7 +199,7 @@
                         <label><strong>{{paras.parameters[paraIndex]["name"]}}</strong></label>
                         <p v-if="nowNode['isInLoop']"><input onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["relative"]'></input>Use relative XPath</p>
                         <p>XPATH: <span style="font-size: 30px!important;" title="Relative XPATH writing: start with /, e.g. the loop item XPATH is /html/body/div[1], your input is /*[@id='tab-customer'], then the final addressed xpath is: /html/body/div[1]/*[@id='tab-customer']">☺</span></p>
-                        <textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["relativeXPath"]'></textarea>
+                        <textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["relativeXPath"]' placeholder="If you want to write the XPath relative to the current element in the loop, you can write as *../div[1] which matches the first div child element of the parent of the current element in the loop."></textarea>
                         <p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(paras.parameters[paraIndex]['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">Click here to view other equivalent XPath expressions</button></p>
                         <p style="margin-top: 10px">
                             <a class="btn btn-primary" data-toggle="collapse" href="#elementAdvanced" role="button" aria-expanded="false" aria-controls="collapseExample">

+ 6 - 1
ElectronJS/src/taskGrid/FlowChart_CN.html

@@ -129,6 +129,11 @@
                     </div>
                     <label>点击后页面加载最长等待时间(秒):</label>
                     <input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['maxWaitTime']" type="number" required></input>
+                    <label>点击类型:</label>
+                    <select v-model='nowNode["parameters"]["clickWay"]' class="form-control">
+                        <option :value = 0>Selenium点击</option>
+                        <option :value = 1>JavaScript点击</option>
+                    </select>
                     <label>点击后是否向下滚动页面:</label>
                     <select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
                         <option value = 0>不滚动</option>
@@ -194,7 +199,7 @@
                         <label><strong>{{paras.parameters[paraIndex]["name"]}}</strong></label>
                         <p v-if="nowNode['isInLoop']"><input onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["relative"]'></input>使用相对循环内的XPATH</p>
                         <p>XPath: <span style="font-size: 30px!important;" title="相对XPATH写法:以/开头,如循环项XPATH为/html/body/div[1],您的输入为/*[@id='tab-customer'],则最终寻址的xpath为:/html/body/div[1]/*[@id='tab-customer']">☺</span></p>
-                        <textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["relativeXPath"]'></textarea>
+                        <textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='paras.parameters[paraIndex]["relativeXPath"]' placeholder="如果要写相对循环内的xpath,可以写如*../div[1]即匹配当前循环元素的父元素的第一个div子元素"></textarea>
                         <p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(paras.parameters[paraIndex]['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">点此查看其他等价的XPath</button></p>
                         <p style="margin-top: 10px">
                             <a class="btn btn-primary" data-toggle="collapse" href="#elementAdvanced" role="button" aria-expanded="false" aria-controls="collapseExample">

+ 1 - 0
ElectronJS/src/taskGrid/logic.js

@@ -158,6 +158,7 @@ function addParameters(t) {
         t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部
         t["parameters"]["scrollCount"] = 1; //滚动次数
         t["parameters"]["scrollWaitTime"] = 1; //滚动后等待时间
+        t["parameters"]["clickWay"] = 0; //点击方式,0代表selenium点击,1代表js点击
         t["parameters"]["maxWaitTime"] = 10; //最长等待时间
         t["parameters"]["paras"] = []; //默认参数列表
         t["parameters"]["wait"] = 2; //点击后等待时间默认2s

+ 1 - 0
ElectronJS/src/taskGrid/logic_CN.js

@@ -158,6 +158,7 @@ function addParameters(t) {
         t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部
         t["parameters"]["scrollCount"] = 1; //滚动次数
         t["parameters"]["scrollWaitTime"] = 1; //滚动后等待时间
+        t["parameters"]["clickWay"] = 0; //点击方式,0代表selenium点击,1代表js点击
         t["parameters"]["maxWaitTime"] = 10; //最长等待时间
         t["parameters"]["paras"] = []; //默认参数列表
         t["parameters"]["wait"] = 2; //点击后等待时间默认2s

文件差異過大導致無法顯示
+ 0 - 0
ElectronJS/tasks/102.json


文件差異過大導致無法顯示
+ 0 - 0
ElectronJS/tasks/103.json


文件差異過大導致無法顯示
+ 0 - 0
ElectronJS/tasks/104.json


文件差異過大導致無法顯示
+ 0 - 0
ElectronJS/tasks/105.json


+ 1 - 1
ExecuteStage/.vscode/launch.json

@@ -12,7 +12,7 @@
             "console": "integratedTerminal",
             "justMyCode": true,
             // "args": ["--id", "38", "--read_type", "local", "--headless", "1"]
-            "args": ["--id", "[2]", "--headless", "0", "--user_data", "0"]
+            "args": ["--id", "[99]", "--headless", "0", "--user_data", "1"]
         }
     ]
 }

+ 1 - 1
ExecuteStage/config.json

@@ -2,5 +2,5 @@
     "webserver_address": "http://localhost",
     "webserver_port": 8074,
     "user_data_folder": "./user_data",
-    "absolute_user_data_folder": "D:\\Documents\\Projects\\EasySpider\\ElectronJS\\user_data"
+    "absolute_user_data_folder": "D:\\Documents\\Projects\\EasySpider\\.temp_to_pub\\EasySpider_windows_x64\\user_data"
 }

+ 12 - 4
ExecuteStage/easyspider_executestage.py

@@ -760,9 +760,17 @@ class BrowserThread(Thread):
                     path + ", please try to set the wait time before executing this operation")
         tempHandleNum = len(self.browser.window_handles)  # 记录之前的窗口位置
         try:
-            script = 'var result = document.evaluate(`' + path + \
-                '`, document, null, XPathResult.ANY_TYPE, null);for(let i=0;i<arguments[0];i++){result.iterateNext();} result.iterateNext().click();'
-            self.browser.execute_script(script, str(index))  # 用js的点击方法
+            click_way = int(para["clickWay"])
+        except:
+            click_way = 0
+        try:
+            if click_way == 0: # 用selenium的点击方法
+                actions = ActionChains(self.browser)  # 实例化一个action对象
+                actions.click(element).perform()
+            elif click_way == 1: # 用js的点击方法
+                script = 'var result = document.evaluate(`' + path + \
+                    '`, document, null, XPathResult.ANY_TYPE, null);for(let i=0;i<arguments[0];i++){result.iterateNext();} result.iterateNext().click();'
+                self.browser.execute_script(script, str(index))  # 用js的点击方法
         except TimeoutException:
             self.Log('time out after set seconds when loading clicked page')
             self.recordLog('time out after set seconds when loading clicked page')
@@ -936,7 +944,7 @@ class BrowserThread(Thread):
                                                                 p["relativeXPath"][1:])
                     else:
                         element = self.browser.find_element(By.XPATH, p["relativeXPath"])
-                except (NoSuchElementException, InvalidSelectorException):  # 找不到元素的时候,使用默认值
+                except (NoSuchElementException, InvalidSelectorException, StaleElementReferenceException):  # 找不到元素的时候,使用默认值
                     # print(p)
                     try:
                         content = p["default"]

+ 3 - 0
Extension/manifest_v3/src/content-scripts/messageInteraction.js

@@ -57,6 +57,7 @@ export function input(value) {
 export function sendSingleClick() {
     let message = {
         "type": "singleClick",
+        "id": global.id,
         "history": history.length, //记录history的长度
         "tabIndex": -1,
         "useLoop": false, //是否使用循环内元素
@@ -208,6 +209,7 @@ export function collectMultiWithPattern() {
 export function sendLoopClickSingle(name) {
     let message = {
         "type": "loopClickSingle",
+        "id": global.id,
         "history": history.length, //记录history的长度
         "tabIndex": -1,
         "useLoop": true, //是否使用循环内元素
@@ -231,6 +233,7 @@ export function sendLoopClickSingle(name) {
 export function sendLoopClickEvery() {
     let message = {
         "type": "loopClickEvery",
+        "id": global.id,
         "history": history.length, //记录history的长度
         "tabIndex": -1,
         "xpath": "", //默认值设置为空

+ 10 - 7
Extension/manifest_v3/src/content-scripts/toolkit.vue

@@ -465,11 +465,12 @@ export default {
           }
         }
     },
-    clickElement: function () { //点击元素操作
+    clickElement: async function () { //点击元素操作
       sendSingleClick();
       //先发送数据
       global.nodeList[0]["node"].focus(); //获得元素焦点
-      global.nodeList[0]["node"].click(); //点击元素
+      await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
+      // global.nodeList[0]["node"].click(); //点击元素
       clearEl();
     },
     changeSelect: function(){
@@ -527,18 +528,20 @@ export default {
       sendLoopMouseMove();
       clearEl();
     },
-    loopClickSingleElement: function () { //循环点击单个元素
+    loopClickSingleElement: async function () { //循环点击单个元素
       sendLoopClickSingle(this.tname()); //识别下一页,循环点击单个元素和点击多个元素
       // if (this.tname() != "下一页元素") { //下一页元素不进行点击操作
-        global.nodeList[0]["node"].focus(); //获得元素焦点
-        global.nodeList[0]["node"].click(); //点击元素
+      global.nodeList[0]["node"].focus(); //获得元素焦点
+      await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
+      // global.nodeList[0]["node"].click(); //点击元素
       // }
       clearEl();
     },
-    loopClickEveryElement: function () { //循环点击每个元素
+    loopClickEveryElement: async function () { //循环点击每个元素
       sendLoopClickEvery(); //识别下一页,循环点击单个元素和点击多个元素
       global.nodeList[0]["node"].focus(); //获得元素焦点
-      global.nodeList[0]["node"].click(); //点击元素
+      await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
+      // global.nodeList[0]["node"].click(); //点击元素
       clearEl();
     },
     setInput: function () { //输入文字

部分文件因文件數量過多而無法顯示