1
0
Эх сурвалжийг харах

Navigation about Next Page!!!

naibo 1 жил өмнө
parent
commit
be2f980734

BIN
ElectronJS/EasySpider_en.crx


BIN
ElectronJS/EasySpider_zh.crx


+ 10 - 2
ElectronJS/main.js

@@ -470,8 +470,16 @@ async function beginInvoke(msg, ws) {
                     try {
                     try {
                         await driver.get(url);
                         await driver.get(url);
                     } catch (e) {
                     } catch (e) {
-                        driver.switchTo().window(current_handle);
-                        await driver.get(url);
+                        try {
+                            await driver.switchTo().window(current_handle);
+                            await driver.get(url);
+                        } catch (e){
+                            let all_handles = await driver.getAllWindowHandles();
+                            let handle = all_handles[all_handles.length - 1];
+                            await driver.switchTo().window(handle);
+                            await driver.get(url);
+                        }
+
                     }
                     }
                 } else if (option == 2 || option == 7) { //点击事件
                 } else if (option == 2 || option == 7) { //点击事件
                     let elementInfo = {"iframe": parameters.iframe, "xpath": parameters.xpath, "id": -1};
                     let elementInfo = {"iframe": parameters.iframe, "xpath": parameters.xpath, "id": -1};

+ 5 - 2
ElectronJS/src/taskGrid/FlowChart.html

@@ -698,6 +698,11 @@ If the expression returns a value greater than 0 or evaluates to True, the opera
                     </select>
                     </select>
                     <label>Export File Name/Database Table Name (Can use ../ to represent relative path to change the file save location,the keyword "current_time" will be replaced with the timestamp when the task is executed):</label>
                     <label>Export File Name/Database Table Name (Can use ../ to represent relative path to change the file save location,the keyword "current_time" will be replaced with the timestamp when the task is executed):</label>
                     <input onkeydown="inputDelete(event)" value="current_time" id="saveName" class="form-control"></input>
                     <input onkeydown="inputDelete(event)" value="current_time" id="saveName" class="form-control"></input>
+                    <label>Data Write Mode (The export file/database table name above must be fixed, effective when the same task ID is executed multiple times):</label>
+                    <select id="dataWriteMode" name="dataWriteMode" class="form-control">
+                        <option value="1">Append (If the file exists, append to it)</option>
+                        <option value="2">Overwrite (If the file exists, overwrite it)</option>
+                    </select>
 <!--                    <label>Is it an extreme anti-scraping website like Cloudflare (<a href="https://www.bilibili.com/video/BV1Ph4y1E7R9/" target="_blank">Watch Tutorial</a>)?</label>-->
 <!--                    <label>Is it an extreme anti-scraping website like Cloudflare (<a href="https://www.bilibili.com/video/BV1Ph4y1E7R9/" target="_blank">Watch Tutorial</a>)?</label>-->
 <!--                    <select id="cloudflare" name="cloudflare" class="form-control">-->
 <!--                    <select id="cloudflare" name="cloudflare" class="form-control">-->
 <!--                        <option value=0>No</option>-->
 <!--                        <option value=0>No</option>-->
@@ -722,8 +727,6 @@ If the expression returns a value greater than 0 or evaluates to True, the opera
                         <option value="0">No</option>
                         <option value="0">No</option>
                         <option value="1">Yes (Requires running the same task ID and the same file name, please execute from the command line and specify the ID)</option>
                         <option value="1">Yes (Requires running the same task ID and the same file name, please execute from the command line and specify the ID)</option>
                     </select>
                     </select>
-<!--                    <label>Wait time for the browser to close after the task is executed (in seconds):</label>-->
-                    <label>任务执行完毕后自动关闭浏览器等待秒数(用户临时目录将在浏览器关闭后自动删除):</label>
                     <label>Wait time for the browser to close after the task is executed (in seconds), the temporary user data directory will be automatically deleted after the browser is closed:</label>
                     <label>Wait time for the browser to close after the task is executed (in seconds), the temporary user data directory will be automatically deleted after the browser is closed:</label>
                     <input onkeydown="inputDelete(event)" type="number" value="60" id="quitWaitTime" name="quitWaitTime" class="form-control"></input>
                     <input onkeydown="inputDelete(event)" type="number" value="60" id="quitWaitTime" name="quitWaitTime" class="form-control"></input>
                     <label>Maximum Display Length of Data in Console Preview:</label>
                     <label>Maximum Display Length of Data in Console Preview:</label>

+ 6 - 3
ElectronJS/src/taskGrid/FlowChart.js

@@ -436,7 +436,7 @@ function operationChange(e, theNode) {
     vueData.nowNodeIndex = actionSequence[theNode.getAttribute("data")];
     vueData.nowNodeIndex = actionSequence[theNode.getAttribute("data")];
     theNode.style.borderColor = "blue";
     theNode.style.borderColor = "blue";
     handleElement(); //处理元素
     handleElement(); //处理元素
-    if(debuggable){
+    if (debuggable) {
         trailElement(app._data.nowNode, 0);
         trailElement(app._data.nowNode, 0);
     } else {
     } else {
         debuggable = true;
         debuggable = true;
@@ -504,7 +504,8 @@ function toolBoxKernel(e, para = null) {
         // let tarrow = DeepClone(app.$data.nowArrow);
         // let tarrow = DeepClone(app.$data.nowArrow);
         // refresh();
         // refresh();
         // app._data.nowArrow =tarrow;
         // app._data.nowArrow =tarrow;
-    } else if (option == 11) { //复制操作
+    }
+    else if (option == 11) { //复制操作
         if (nowNode == null) {
         if (nowNode == null) {
             e.stopPropagation(); //防止冒泡
             e.stopPropagation(); //防止冒泡
         } else if (nowNode.getAttribute("dataType") > 0) {
         } else if (nowNode.getAttribute("dataType") > 0) {
@@ -568,7 +569,9 @@ function toolBoxKernel(e, para = null) {
             } else {
             } else {
                 showError(LANG("自己不能移动到自己的节点里!", "Cannot move inside self!"));
                 showError(LANG("自己不能移动到自己的节点里!", "Cannot move inside self!"));
             }
             }
-            e.stopPropagation(); //防止冒泡
+            if (e != null) {
+                e.stopPropagation(); //防止冒泡
+            }
         }
         }
     }
     }
     else if (option > 0) { //新增操作
     else if (option > 0) { //新增操作

+ 5 - 0
ElectronJS/src/taskGrid/FlowChart_CN.html

@@ -698,6 +698,11 @@ print(emotlib.emoji()) # 使用其中的函数。
                     </select>
                     </select>
                     <label>导出文件名/数据库表格名称(可使用../表示相对路径以改变文件保存位置,名称中的“current_time”会被替换为执行任务时的时间戳):</label>
                     <label>导出文件名/数据库表格名称(可使用../表示相对路径以改变文件保存位置,名称中的“current_time”会被替换为执行任务时的时间戳):</label>
                     <input onkeydown="inputDelete(event)" value="current_time" id="saveName" class="form-control"></input>
                     <input onkeydown="inputDelete(event)" value="current_time" id="saveName" class="form-control"></input>
+                    <label>数据写入模式(上方导出文件名/数据库表格名称需固定,同一个任务ID多次执行时生效):</label>
+                    <select id="dataWriteMode" name="dataWriteMode" class="form-control">
+                        <option value=1>追加写入(如果文件已存在则在原文件后面追加)</option>
+                        <option value=2>覆盖写入(如果文件已存在则覆盖原文件)</option>
+                    </select>
 <!--                    <label>是否为Cloudflare等极端反爬网站(<a href="https://www.bilibili.com/video/BV1Ph4y1E7R9/" target="_blank">查看Cloudflare设计和执行教程</a>):</label>-->
 <!--                    <label>是否为Cloudflare等极端反爬网站(<a href="https://www.bilibili.com/video/BV1Ph4y1E7R9/" target="_blank">查看Cloudflare设计和执行教程</a>):</label>-->
 <!--                    <select id="cloudflare" name="cloudflare" class="form-control">-->
 <!--                    <select id="cloudflare" name="cloudflare" class="form-control">-->
 <!--                        <option value = 0>否</option>-->
 <!--                        <option value = 0>否</option>-->

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

@@ -105,6 +105,35 @@ function handleAddElement(msg) {
         addElement(8, msg);
         addElement(8, msg);
         msg["xpath"] = ""; //循环点击每个元素,单个元素的xpath设置为空
         msg["xpath"] = ""; //循环点击每个元素,单个元素的xpath设置为空
         addElement(2, msg);
         addElement(2, msg);
+    } else if (msg["type"] == "loopClickNextPage") {
+        let withLoop = msg.lastAction.includes("WithLoop"); //最后一个操作是否是循环操作
+        if (withLoop) {
+            //如果之前是循环提取数据操作,锚点先调整到循环提取数据操作下方
+            let loopElementId = app._data.nowArrow["pId"];
+            let loopElement = $("#" + loopElementId);
+            app._data.nowArrow["position"] = loopElement.attr("position");
+            app._data.nowArrow["pId"] = loopElement.attr("pId");
+        }
+        //按照循环点击元素的方式添加操作
+        addElement(8, msg);
+        msg["xpath"] = ""; //循环点击下一页,单个元素的xpath设置为空
+        addElement(2, msg);
+        //parentId是在actionSequence中的位置,nodeList[actionSequence[parentId]]才是父元素
+        //position是在父元素的sequence中的位置,nodeList[actionSequence[parentId]]["sequence"][position]才是该元素在nodeList中的位置,actionSequence[id]
+        let parentNode = nodeList[actionSequence[app._data.nowNode["parentId"]]]; //获取当前操作,即点击下一页操作的父元素,即循环操作
+        let parent_position = parentNode["position"];
+        let last_collect_data_node_position = parent_position - 1; //循环操作的上一个操作一般是提取数据操作
+        let parent_parentId = parentNode["parentId"]; //循环操作的父元素的id
+        let last_collect_data_node_index = nodeList[actionSequence[parent_parentId]]["sequence"][last_collect_data_node_position]; //提取数据操作在nodeList中的位置
+        let last_collect_data_node = nodeList[last_collect_data_node_index]; //提取数据操作
+        $("#" + last_collect_data_node["id"]).click(); //点击提取数据元素
+        app._data.nowArrow['position'] = -1; //循环点击下一页,下一个要插入的位置一般在元素上方
+        option = 10; //剪切操作
+        toolBoxKernel(null, null); //剪切操作
+        //切换到循环点击下一页操作
+        parentNode = nodeList[actionSequence[app._data.nowNode["parentId"]]]; //获取当前操作,即点击下一页操作的父元素,即循环操作
+        let parentId = parentNode["id"]; //循环操作的id
+        $("#" + parentId).click(); //点击循环操作
     } else if (msg["type"] == "singleCollect" || msg["type"] == "multiCollectNoPattern") {
     } else if (msg["type"] == "singleCollect" || msg["type"] == "multiCollectNoPattern") {
         if (app._data.nowNode != null && app._data["nowNode"]["option"] == 3) { //如果现在节点就是提取数据节点,直接在此节点添加参数,而不是生成一个新的提取数据节点
         if (app._data.nowNode != null && app._data["nowNode"]["option"] == 3) { //如果现在节点就是提取数据节点,直接在此节点添加参数,而不是生成一个新的提取数据节点
             for (let i = 0; i < msg["parameters"].length; i++) {
             for (let i = 0; i < msg["parameters"].length; i++) {
@@ -552,6 +581,7 @@ function saveService(type) {
         "recordLog": parseInt($("#recordLog").val()),
         "recordLog": parseInt($("#recordLog").val()),
         "outputFormat": $("#outputFormat").val(),
         "outputFormat": $("#outputFormat").val(),
         "saveName": $("#saveName").val(),
         "saveName": $("#saveName").val(),
+        "dataWriteMode": parseInt($("#dataWriteMode").val()),
         "inputExcel": $("#inputExcel").val(),
         "inputExcel": $("#inputExcel").val(),
         "startFromExit": parseInt($("#startFromExit").val()),
         "startFromExit": parseInt($("#startFromExit").val()),
         "pauseKey": $("#pauseKey").val(),
         "pauseKey": $("#pauseKey").val(),

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
ElectronJS/tasks/260.json


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
ElectronJS/tasks/273.json


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
ElectronJS/tasks/274.json


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
ElectronJS/tasks/275.json


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

@@ -12,7 +12,7 @@
             "justMyCode": false,
             "justMyCode": false,
             //  "args": ["--ids", "[7]", "--read_type", "remote", "--headless", "0"]
             //  "args": ["--ids", "[7]", "--read_type", "remote", "--headless", "0"]
             // "args": ["--ids", "[9]", "--read_type", "remote", "--headless", "0", "--saved_file_name", "YOUTUBE"]
             // "args": ["--ids", "[9]", "--read_type", "remote", "--headless", "0", "--saved_file_name", "YOUTUBE"]
-            "args": ["--ids", "[38]", "--headless", "0", "--user_data", "0", "--keyboard", "0",
+            "args": ["--ids", "[47]", "--headless", "0", "--user_data", "0", "--keyboard", "0",
         "--read_type", "remote"]
         "--read_type", "remote"]
             // "args": "--ids '[97]' --user_data 1 --server_address http://localhost:8074 --config_folder '/Users/naibo/Documents/EasySpider/ElectronJS/' --headless 0 --read_type remote --config_file_name config.json --saved_file_name"
             // "args": "--ids '[97]' --user_data 1 --server_address http://localhost:8074 --config_folder '/Users/naibo/Documents/EasySpider/ElectronJS/' --headless 0 --read_type remote --config_file_name config.json --saved_file_name"
         }
         }

+ 8 - 1
ExecuteStage/easyspider_executestage.py

@@ -175,6 +175,13 @@ class BrowserThread(Thread):
         except:
         except:
             self.links = list(filter(isnotnull, service["url"]))  # 要执行的link
             self.links = list(filter(isnotnull, service["url"]))  # 要执行的link
         self.OUTPUT = []  # 采集的数据
         self.OUTPUT = []  # 采集的数据
+        try:
+            self.dataWriteMode = service["dataWriteMode"] # 数据写入模式,1为追加,2为覆盖
+        except:
+            self.dataWriteMode = 1
+        if self.outputFormat == "csv" or self.outputFormat == "txt" or self.outputFormat == "xlsx" or self.outputFormat == "json":
+            if self.dataWriteMode == 2 and os.path.exists("Data/Task_" + str(self.id) + "/" + self.saveName + '.' + self.outputFormat):
+                os.remove("Data/Task_" + str(self.id) + "/" + self.saveName + '.' + self.outputFormat)
         self.writeMode = 1  # 写入模式,0为新建,1为追加
         self.writeMode = 1  # 写入模式,0为新建,1为追加
         if self.outputFormat == "csv" or self.outputFormat == "txt" or self.outputFormat == "xlsx":
         if self.outputFormat == "csv" or self.outputFormat == "txt" or self.outputFormat == "xlsx":
             if not os.path.exists("Data/Task_" + str(self.id) + "/" + self.saveName + '.' + self.outputFormat):
             if not os.path.exists("Data/Task_" + str(self.id) + "/" + self.saveName + '.' + self.outputFormat):
@@ -184,7 +191,7 @@ class BrowserThread(Thread):
             self.writeMode = 3  # JSON模式无需判断是否存在文件
             self.writeMode = 3  # JSON模式无需判断是否存在文件
         elif self.outputFormat == "mysql":
         elif self.outputFormat == "mysql":
             self.mysql = myMySQL(config["mysql_config_path"])
             self.mysql = myMySQL(config["mysql_config_path"])
-            self.mysql.create_table(self.saveName, service["outputParameters"])
+            self.mysql.create_table(self.saveName, service["outputParameters"], remove_if_exists=self.dataWriteMode == 2)
             self.writeMode = 2
             self.writeMode = 2
         if self.writeMode == 0:
         if self.writeMode == 0:
             self.print_and_log("新建模式|Create Mode")
             self.print_and_log("新建模式|Create Mode")

+ 8 - 3
ExecuteStage/utils.py

@@ -417,13 +417,18 @@ class myMySQL:
                 "Failed to connect to the database, please check if the configuration file is correct.")
                 "Failed to connect to the database, please check if the configuration file is correct.")
             sys.exit()
             sys.exit()
 
 
-    def create_table(self, table_name, parameters):
+    def create_table(self, table_name, parameters, remove_if_exists=False):
         self.table_name = table_name
         self.table_name = table_name
         self.field_sql = "("
         self.field_sql = "("
         self.cursor = self.conn.cursor()
         self.cursor = self.conn.cursor()
         # 检查表是否存在
         # 检查表是否存在
         self.cursor.execute(f"SHOW TABLES LIKE '{table_name}'")
         self.cursor.execute(f"SHOW TABLES LIKE '{table_name}'")
         result = self.cursor.fetchone()
         result = self.cursor.fetchone()
+        # 如果表存在,删除它
+        if result and remove_if_exists:
+            self.cursor.execute(f"DROP TABLE {table_name}")
+            result = None
+            print(f'数据表 {table_name} 已存在,已删除。')
 
 
         sql = "CREATE TABLE " + table_name + \
         sql = "CREATE TABLE " + table_name + \
             " (_id INT AUTO_INCREMENT PRIMARY KEY, "
             " (_id INT AUTO_INCREMENT PRIMARY KEY, "
@@ -510,8 +515,8 @@ class myMySQL:
             for i in range(len(line)):
             for i in range(len(line)):
                 if record[i]:
                 if record[i]:
                     to_write.append(line[i])
                     to_write.append(line[i])
-            # 构造插入数据的 SQL 语句
-            sql = f'INSERT INTO {self.table_name} {self.field_sql} VALUES ('
+            # 构造插入数据的 SQL 语句, IGNORE表示如果主键重复则忽略
+            sql = f'INSERT IGNORE INTO {self.table_name} {self.field_sql} VALUES ('
             for _ in to_write:
             for _ in to_write:
                 sql += "%s, "
                 sql += "%s, "
             # 移除最后的逗号并添加闭合的括号
             # 移除最后的逗号并添加闭合的括号

+ 2 - 1
Extension/manifest_v3/src/content-scripts/global.js

@@ -239,6 +239,7 @@ export function clearEl(trail=false) {
     global.nodeList.splice(0, global.nodeList.length); //清空数组
     global.nodeList.splice(0, global.nodeList.length); //清空数组
     global.app._data.option = 0; //选项重置
     global.app._data.option = 0; //选项重置
     global.app._data.page = 0; //恢复原始页面
     global.app._data.page = 0; //恢复原始页面
+    // global.app._data.nextPage = 0; //不出现翻页操作提示
 }
 }
 
 
 
 
@@ -271,6 +272,7 @@ export function clearParameters(deal = true) //清空参数列表
     if (deal) //是否取消对选中的子元素进行处理
     if (deal) //是否取消对选中的子元素进行处理
     {
     {
         global.app._data.selectedDescendents = false;
         global.app._data.selectedDescendents = false;
+        global.app._data.selectStatus = false;
     }
     }
     for (let o of global.outputParameterNodes) {
     for (let o of global.outputParameterNodes) {
         o["node"].style.boxShadow = o["boxShadow"];
         o["node"].style.boxShadow = o["boxShadow"];
@@ -278,7 +280,6 @@ export function clearParameters(deal = true) //清空参数列表
     global.outputParameterNodes.splice(0);
     global.outputParameterNodes.splice(0);
     global.outputParameters.splice(0); //清空原来的参数列表
     global.outputParameters.splice(0); //清空原来的参数列表
     global.app._data.valTable = []; //清空展现数组
     global.app._data.valTable = []; //清空展现数组
-    global.app._data.selectStatus = false;
 }
 }
 
 
 export function LANG(zh, en) {
 export function LANG(zh, en) {

+ 5 - 1
Extension/manifest_v3/src/content-scripts/messageInteraction.js

@@ -258,7 +258,7 @@ export function collectMultiWithPattern() {
 }
 }
 
 
 //循环点击单个元素
 //循环点击单个元素
-export function sendLoopClickSingle(name) {
+export function sendLoopClickSingle(name="") {
     let message = {
     let message = {
         "type": "loopClickSingle",
         "type": "loopClickSingle",
         "id": global.id,
         "id": global.id,
@@ -271,9 +271,13 @@ export function sendLoopClickSingle(name) {
         "allXPaths": getElementXPaths(global.nodeList[0]["node"]),
         "allXPaths": getElementXPaths(global.nodeList[0]["node"]),
         "loopType": 0, //循环类型,0为单个元素
         "loopType": 0, //循环类型,0为单个元素
         "nextPage": false, //是否循环点击下一页
         "nextPage": false, //是否循环点击下一页
+        "lastAction": global.app._data.lastAction,
     };
     };
     if (name == "下一页元素") {
     if (name == "下一页元素") {
         message.nextPage = true;
         message.nextPage = true;
+    } else if(name == "nextPageFromIndexPage") {
+        message.nextPage = true;
+        message.type = "loopClickNextPage";
     }
     }
     let message_action = {
     let message_action = {
         type: 3, //消息类型,3代表元素增加事件
         type: 3, //消息类型,3代表元素增加事件

+ 188 - 111
Extension/manifest_v3/src/content-scripts/toolkit.vue

@@ -9,15 +9,19 @@
       <div class="realcontent">
       <div class="realcontent">
         <div v-if="page==0">
         <div v-if="page==0">
           <div v-if="list.nl.length==0" :style="{overflow: 'auto', maxHeight: winHeight * 0.4 + 'px'}">
           <div v-if="list.nl.length==0" :style="{overflow: 'auto', maxHeight: winHeight * 0.4 + 'px'}">
-            <input style="width:15px;height:15px;vertical-align:middle;" type="checkbox"
-                   v-on:mousedown="specialSelect"/>
-            <p style="margin-bottom:10px;display:inline-block">特殊点选模式<span
-                title="普通模式下如果不能选中元素可以勾选此项">☺</span></p>
+            <!--            <input style="width:15px;height:15px;vertical-align:middle;" type="checkbox"-->
+            <!--                   v-on:mousedown="specialSelect"/>-->
+            <!--            <p style="margin-bottom:10px;display:inline-block">特殊点选模式<span-->
+            <!--                title="普通模式下如果不能选中元素可以勾选此项">☺</span></p>-->
+            <p style="color: darkviolet;" v-if="nextPage==1">
+              ● 检测到您刚刚进行了采集数据的操作,如需设置翻页操作,请点击下方设置翻页操作选项。</p>
             <div class="innercontent" v-if="list.nl.length==0">
             <div class="innercontent" v-if="list.nl.length==0">
+              <div v-if="nextPage==1" class="nextPage">
+                <a v-on:mousedown="setNextPage">设置翻页操作</a><span title="可根据提示指定翻页按钮">☺</span></div>
               <div><a v-on:mousedown="getCurrentTitle">采集当前页面的标题</a><span title="当前页面标题">☺</span></div>
               <div><a v-on:mousedown="getCurrentTitle">采集当前页面的标题</a><span title="当前页面标题">☺</span></div>
               <div><a v-on:mousedown="getCurrentURL">采集当前页面的网址</a><span title="当前页面URL地址">☺</span></div>
               <div><a v-on:mousedown="getCurrentURL">采集当前页面的网址</a><span title="当前页面URL地址">☺</span></div>
             </div>
             </div>
-            <p style="color:black; margin-top: 10px">● 鼠标移动到笑脸☺查看操作提示。</p>
+            <p style="color:black; margin-top: 10px">● 鼠标移动到笑脸<span style="font-size: 20px"></span>查看操作提示。</p>
             <p style="color:black; margin-top: 10px">●
             <p style="color:black; margin-top: 10px">●
               鼠标移动到元素上后,请<strong>右键</strong>点击或者按<strong>F7</strong>键选中页面元素。
               鼠标移动到元素上后,请<strong>右键</strong>点击或者按<strong>F7</strong>键选中页面元素。
             </p>
             </p>
@@ -147,7 +151,7 @@
             </div>
             </div>
           </div>
           </div>
 
 
-          <div v-if="valTable.length==0&&tname()!='下一页元素'"></div>
+          <!--          <div v-if="valTable.length==0&&tname()!='下一页元素'"></div>-->
 
 
           <div v-if="list.nl.length>0"
           <div v-if="list.nl.length>0"
                style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
                style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
@@ -158,7 +162,7 @@
             <p style="margin-left:16px;margin-bottom:0px">{{ lastElementXPath() }}</p>
             <p style="margin-left:16px;margin-bottom:0px">{{ lastElementXPath() }}</p>
           </div>
           </div>
         </div>
         </div>
-        <div v-if="page==1">
+        <div v-else-if="page==1">
           ● 请输入文字:
           ● 请输入文字:
           <input id="WTextBox" v-model="text" autoFocus="autofocus" type="text"></input>
           <input id="WTextBox" v-model="text" autoFocus="autofocus" type="text"></input>
           <button style="margin-left:0px!important;" v-on:click="getInput">确定</button>
           <button style="margin-left:0px!important;" v-on:click="getInput">确定</button>
@@ -167,7 +171,7 @@
             输入&lt;enter&gt;或&lt;ENTER&gt;表示输入完成后模拟按下回车键,适用于只能通过回车键获得数据的情况。
             输入&lt;enter&gt;或&lt;ENTER&gt;表示输入完成后模拟按下回车键,适用于只能通过回车键获得数据的情况。
           </div>
           </div>
         </div>
         </div>
-        <div v-if="page==2">
+        <div v-else-if="page==2">
           <span style="font-size: 15px"> ● 切换模式 </span>
           <span style="font-size: 15px"> ● 切换模式 </span>
           <select v-model="optionMode" @change="handleSelectChange">
           <select v-model="optionMode" @change="handleSelectChange">
             <option value=0>切换到下一个选项</option>
             <option value=0>切换到下一个选项</option>
@@ -185,6 +189,21 @@
             <button style="margin-left:0px!important;" v-on:click="cancelInput">取消</button>
             <button style="margin-left:0px!important;" v-on:click="cancelInput">取消</button>
           </div>
           </div>
         </div>
         </div>
+        <div v-else-if="page==3">
+          <span
+              style="font-size: 15px"> ● 请在页面上右键选择要点击的下一页按钮/链接,如要取消设置翻页操作,请点击下方取消选项。</span>
+          <div style="font-size: 15px" v-if="list.nl.length==1">
+            ● 已选中一个元素,您可以点击下方选项确认设置翻页操作。
+          </div>
+          <div style="font-size: 15px; color: #c82333;" v-else-if="list.nl.length>1">
+            ● 翻页操作只能设置一个元素,请点击下方取消翻页操作选项并重新选择。
+          </div>
+          <div class="innercontent">
+            <div><a href="#" v-on:mousedown="confirmNextPage" v-if="list.nl.length==1" style="margin-bottom: 5px">确认设置翻页操作</a>
+            </div>
+            <div><a href="#" v-on:mousedown="cancelNextPage">取消设置翻页操作</a></div>
+          </div>
+        </div>
       </div>
       </div>
     </div>
     </div>
     <div v-else-if="lang=='en'">
     <div v-else-if="lang=='en'">
@@ -192,17 +211,23 @@
       <div class="realcontent">
       <div class="realcontent">
         <div v-if="page==0">
         <div v-if="page==0">
           <div v-if="list.nl.length==0" :style="{overflow: 'auto', maxHeight: winHeight * 0.4 + 'px'}">
           <div v-if="list.nl.length==0" :style="{overflow: 'auto', maxHeight: winHeight * 0.4 + 'px'}">
-            <input style="width:15px;height:15px;vertical-align:middle;" type="checkbox"
-                   v-on:mousedown="specialSelect"> </input>
-            <p style="margin-bottom:10px;display:inline-block">Special click mode<span
-                title="If cannot select element by mouse, select this option">☺</span></p>
+            <!--            <input style="width:15px;height:15px;vertical-align:middle;" type="checkbox"-->
+            <!--                   v-on:mousedown="specialSelect"> </input>-->
+            <!--            <p style="margin-bottom:10px;display:inline-block">Special click mode<span-->
+            <!--                title="If cannot select element by mouse, select this option">☺</span></p>-->
+            <p style="color: darkviolet;" v-if="nextPage==1">
+              ● A data collection operation has just been detected. If you need to configure pagination, please click
+              the option below to set up pagination.</p>
             <div class="innercontent" v-if="list.nl.length==0">
             <div class="innercontent" v-if="list.nl.length==0">
+              <div v-if="nextPage==1" class="nextPage">
+                <a v-on:mousedown="setNextPage">Set up pagination</a><span
+                  title="Follow the prompt to specify the paging button">☺</span></div>
               <div><a v-on:mousedown="getCurrentTitle">Collect Title of current page</a><span
               <div><a v-on:mousedown="getCurrentTitle">Collect Title of current page</a><span
                   title="Title of this page">☺</span></div>
                   title="Title of this page">☺</span></div>
               <div><a v-on:mousedown="getCurrentURL">Collect URL of current page</a><span
               <div><a v-on:mousedown="getCurrentURL">Collect URL of current page</a><span
                   title="URL of this page">☺</span></div>
                   title="URL of this page">☺</span></div>
             </div>
             </div>
-            <p style="color:black; margin-top: 10px">● Mouse move to smiling face ☺ to see operation help.</p>
+            <p style="color:black; margin-top: 10px">● Mouse move to smiling face <span style="font-size: 20px"></span> to see operation help.</p>
             <p style="color:black; margin-top: 10px">● When your mouse moves to the element, please
             <p style="color:black; margin-top: 10px">● When your mouse moves to the element, please
               <strong>right-click</strong> your
               <strong>right-click</strong> your
               mouse button or press <strong>F7</strong> on the keyboard to select it.</p>
               mouse button or press <strong>F7</strong> on the keyboard to select it.</p>
@@ -211,7 +236,8 @@
               lower right corner of this toolbox to close it.</p>
               lower right corner of this toolbox to close it.</p>
             <p style="color:black; margin-top: 10px">● When clicked with the left mouse button, the page will also
             <p style="color:black; margin-top: 10px">● When clicked with the left mouse button, the page will also
               respond, but this click operation will not be recorded in the task flow. Similarly, if you want to input
               respond, but this click operation will not be recorded in the task flow. Similarly, if you want to input
-              in a text box but do not want the action to be recorded , you can move the mouse to the text box and press
+              in a text box but do not want the action to be recorded , you can move the mouse to the text box and
+              press
               <strong>F9</strong> on the keyboard to input.</p>
               <strong>F9</strong> on the keyboard to input.</p>
             <p style="color:black; margin-top: 10px">● If you accidentally left-click on an element and cause the page
             <p style="color:black; margin-top: 10px">● If you accidentally left-click on an element and cause the page
               to jump, simply go back or switch back to the tab.</p>
               to jump, simply go back or switch back to the tab.</p>
@@ -236,7 +262,8 @@
                   <!-- <div v-if="tname()=='selection box'"> <a>循环切换该下拉项</a><span title="">☺</span></div> -->
                   <!-- <div v-if="tname()=='selection box'"> <a>循环切换该下拉项</a><span title="">☺</span></div> -->
                   <div v-if="tname()=='选择框'"><a v-on:mousedown="changeSelect">Change selection option</a><span
                   <div v-if="tname()=='选择框'"><a v-on:mousedown="changeSelect">Change selection option</a><span
                       title=""></span></div>
                       title=""></span></div>
-                  <div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(false)">Input Text</a><span title=""></span>
+                  <div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(false)">Input Text</a><span
+                      title=""></span>
                   </div>
                   </div>
                   <div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(true)">Input Text (Batch)</a><span
                   <div v-if="tname()=='文本框'"><a v-on:mousedown="setInput(true)">Input Text (Batch)</a><span
                       title=""></span>
                       title=""></span>
@@ -280,115 +307,129 @@
               </div>
               </div>
             </div>
             </div>
           </div>
           </div>
-        </div>
 
 
-        <div v-if="list.nl.length>1">
+          <div v-if="list.nl.length>1">
 
 
-          <div v-if="option==100">
-            ● Already selected the following element, you can:
-            <div class="innercontent">
-              <div><a v-on:mousedown="confirmCollectMulti">Collect Data</a><span title=""></span></div>
-              <div><a v-on:mousedown="revoke">Revoke selection</a><span title=""></span></div>
+            <div v-if="option==100">
+              ● Already selected the following element, you can:
+              <div class="innercontent">
+                <div><a v-on:mousedown="confirmCollectMulti">Collect Data</a><span title=""></span></div>
+                <div><a v-on:mousedown="revoke">Revoke selection</a><span title=""></span></div>
+              </div>
             </div>
             </div>
-          </div>
 
 
-          <div v-if="option!=100">
-            ● Already selected {{ numOfList() }} similar elements, <span
-              v-if="numOfReady()>0">and we find other{{ numOfReady() }} similar elements (If unsatisfied with auto-detected similar elements, you can continue to manually select the rest of the elements that you think are similar), </span>you
-            can:
-            <div class="innercontent">
-              <div v-if="numOfReady()>0"><a v-on:mousedown="selectAll">Select All</a><span title=""></span></div>
-              <div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
-                  v-on:mousedown="selectDescendents">Select child elements (Greedy)</a><span
-                  title="Select All child elements for all blocks">☺</span></div>
-              <div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
-                  v-on:mousedown="selectDescendents(1,1)">Select child elements (RFSE)</a><span
-                  title="Relative to First Selected Element, will only select the common child elements between the first selected block and the rest of the blocks">☺</span>
-              </div>
-              <div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
-                  v-on:mousedown="selectDescendents(1,2)">Select child elements (RASE)</a><span
-                  title="Relative to All Selected Elements, will select only the common child elements that exist in all blocks">☺</span>
-              </div>
-              <div><a v-on:mousedown="confirmCollectMultiAndDescendents">Collect Data</a><span title=""></span>
-              </div>
-              <div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
-                  v-on:mousedown="loopClickEveryElement">Loop-click every {{ tname() | toEng }}</a><span
-                  title="Usually used to click every link in a list to open detail page to collect data">☺</span>
+            <div v-if="option!=100">
+              ● Already selected {{ numOfList() }} similar elements, <span
+                v-if="numOfReady()>0">and we find other{{ numOfReady() }} similar elements (If unsatisfied with auto-detected similar elements, you can continue to manually select the rest of the elements that you think are similar), </span>you
+              can:
+              <div class="innercontent">
+                <div v-if="numOfReady()>0"><a v-on:mousedown="selectAll">Select All</a><span title=""></span></div>
+                <div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
+                    v-on:mousedown="selectDescendents">Select child elements (Greedy)</a><span
+                    title="Select All child elements for all blocks">☺</span></div>
+                <div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
+                    v-on:mousedown="selectDescendents(1,1)">Select child elements (RFSE)</a><span
+                    title="Relative to First Selected Element, will only select the common child elements between the first selected block and the rest of the blocks">☺</span>
+                </div>
+                <div v-if="existDescendents()&&(tname()=='元素' || tname()=='链接')"><a
+                    v-on:mousedown="selectDescendents(1,2)">Select child elements (RASE)</a><span
+                    title="Relative to All Selected Elements, will select only the common child elements that exist in all blocks">☺</span>
+                </div>
+                <div><a v-on:mousedown="confirmCollectMultiAndDescendents">Collect Data</a><span title=""></span>
+                </div>
+                <div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
+                    v-on:mousedown="loopClickEveryElement">Loop-click every {{ tname() | toEng }}</a><span
+                    title="Usually used to click every link in a list to open detail page to collect data">☺</span>
+                </div>
+                <div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
+                    v-on:mousedown="loopMouseMove">Loop-mouse-move to every {{ tname() | toEng }}</a><span
+                    title=""></span></div>
+                <div><a v-on:mousedown="revoke">Revoke selection</a><span title=""></span></div>
               </div>
               </div>
-              <div v-if="tname()!='选择框' && tname()!='文本框' && !selectedDescendents"><a
-                  v-on:mousedown="loopMouseMove">Loop-mouse-move to every {{ tname() | toEng }}</a><span
-                  title=""></span></div>
-              <div><a v-on:mousedown="revoke">Revoke selection</a><span title=""></span></div>
             </div>
             </div>
+
           </div>
           </div>
 
 
-        </div>
+          <div v-if="valTable.length>0">
+            <div class="toolkitcontain">
+              <table cellspacing="0" class="toolkittb2">
+                <tbody>
+                <th v-for="(i, index) in list.opp">
+                  <div>{{ i["name"] }}</div>
+                  <span v-bind:index="index" v-on:mousedown="removeField" title="Remove this field">×</span></th>
+                <th style="width:40px">Delete</th>
+                </tbody>
+              </table>
+              <table cellspacing="0" class="toolkittb4">
+                <tbody>
+                <tr v-for="i in valTable[0].length">
+                  <td v-for="j in list.opp.length">{{ valTable[j - 1][i - 1] }}</td>
+                  <td style="font-size: 22px!important;width:40px;cursor:pointer" v-bind:index="i-1"
+                      v-on:mousedown="deleteSingleLine">×
+                  </td>
+                </tr>
+                </tbody>
+              </table>
+            </div>
+          </div>
 
 
-        <div v-if="valTable.length>0">
-          <div class="toolkitcontain">
-            <table cellspacing="0" class="toolkittb2">
-              <tbody>
-              <th v-for="(i, index) in list.opp">
-                <div>{{ i["name"] }}</div>
-                <span v-bind:index="index" v-on:mousedown="removeField" title="Remove this field">×</span></th>
-              <th style="width:40px">Delete</th>
-              </tbody>
-            </table>
-            <table cellspacing="0" class="toolkittb4">
-              <tbody>
-              <tr v-for="i in valTable[0].length">
-                <td v-for="j in list.opp.length">{{ valTable[j - 1][i - 1] }}</td>
-                <td style="font-size: 22px!important;width:40px;cursor:pointer" v-bind:index="i-1"
-                    v-on:mousedown="deleteSingleLine">×
-                </td>
-              </tr>
-              </tbody>
-            </table>
+          <div v-if="valTable.length==0&&tname()!='下一页元素'"></div>
+          <div v-if="list.nl.length>0"
+               style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
+            <div style="margin-bottom:5px">
+              <button v-on:mousedown="cancel">Deselect</button>
+              <button v-if="!selectStatus" v-on:mousedown="enlarge">Expand Path</button>
+            </div>
+            <p style="margin-left:16px;margin-bottom:0px">{{ lastElementXPath() }}</p>
           </div>
           </div>
         </div>
         </div>
-
-        <div v-if="valTable.length==0&&tname()!='下一页元素'"></div>
-
-        <div v-if="list.nl.length>0"
-             style="bottom:12px;position:absolute;color:black!important;left:17px;font-size:13px">
-          <div style="margin-bottom:5px">
-            <button v-on:mousedown="cancel">Deselect</button>
-            <button v-if="!selectStatus" v-on:mousedown="enlarge">Expand Path</button>
+        <div v-else-if="page==1">
+          ● Please input text:
+          <input id="WTextBox" v-model="text" autofocus="autofocus" type="text"></input>
+          <button style="margin-left:0px!important;" v-on:click="getInput">Confirm</button>
+          <button style="margin-left:0px!important;" v-on:click="cancelInput">Cancel</button>
+          <div style="text-align: justify;margin-top: 15px;padding-right: 15px;margin-left: 4px">
+            Inputting &lt;enter&gt; or &lt;ENTER&gt; represents the simulation of pressing the Enter key after input
+            is complete, which is applicable in situations where data can only be obtained through pressing the Enter
+            key.
           </div>
           </div>
-          <p style="margin-left:16px;margin-bottom:0px">{{ lastElementXPath() }}</p>
         </div>
         </div>
-      </div>
-      <div v-if="page==1">
-        ● Please input text:
-        <input id="WTextBox" v-model="text" autofocus="autofocus" type="text"></input>
-        <button style="margin-left:0px!important;" v-on:click="getInput">Confirm</button>
-        <button style="margin-left:0px!important;" v-on:click="cancelInput">Cancel</button>
-        <div style="text-align: justify;margin-top: 15px;padding-right: 15px;margin-left: 4px">
-          Inputting &lt;enter&gt; or &lt;ENTER&gt; represents the simulation of pressing the Enter key after input
-          is complete, which is applicable in situations where data can only be obtained through pressing the Enter
-          key.
+        <div v-else-if="page==2">
+          <span style="font-size: 15px"> ● Change Mode </span>
+          <select v-model="optionMode" @change="handleSelectChange">
+            <option value=0>Change to next option</option>
+            <option value=1>Change option by index</option>
+            <option value=2>Change option by value</option>
+            <option value=3>Change option by text</option>
+          </select>
+          <span style="font-size: 15px" v-if="optionMode == 3"> ● Option Text</span>
+          <span style="font-size: 15px" v-if="optionMode == 1"> ● Option Index</span>
+          <span style="font-size: 15px" v-if="optionMode == 2"> ● Option Value</span>
+          <input id="selectValue" v-if="optionMode != 0" v-model="optionValue" autoFocus="autofocus"
+                 type="text"></input>
+          <div>
+            <button style="margin-left:0px!important;" v-on:click="sendChangeSelect">Confirm</button>
+            <button style="margin-left:0px!important;" v-on:click="cancelInput">Cancel</button>
+          </div>
         </div>
         </div>
-      </div>
-      <div v-if="page==2">
-        <span style="font-size: 15px"> ● Change Mode </span>
-        <select v-model="optionMode" @change="handleSelectChange">
-          <option value=0>Change to next option</option>
-          <option value=1>Change option by index</option>
-          <option value=2>Change option by value</option>
-          <option value=3>Change option by text</option>
-        </select>
-        <span style="font-size: 15px" v-if="optionMode == 3"> ● Option Text</span>
-        <span style="font-size: 15px" v-if="optionMode == 1"> ● Option Index</span>
-        <span style="font-size: 15px" v-if="optionMode == 2"> ● Option Value</span>
-        <input id="selectValue" v-if="optionMode != 0" v-model="optionValue" autoFocus="autofocus"
-               type="text"></input>
-        <div>
-          <button style="margin-left:0px!important;" v-on:click="sendChangeSelect">Confirm</button>
-          <button style="margin-left:0px!important;" v-on:click="cancelInput">Cancel</button>
+        <div v-else-if="page==3">
+          <span style="font-size: 15px"> ● Please right-click on the page and select the next page button/link. To cancel the pagination setup, click the option below.</span>
+          <div style="font-size: 15px" v-if="list.nl.length==1">
+            ● A single element has been selected, you can click the option below to confirm the pagination setup.
+          </div>
+          <div style="font-size: 15px; color: #c82333;" v-else-if="list.nl.length>1">
+            ● The page-turning operation can only be set for one element. Please click the option below to cancel the
+            page-turning operation and reselect.
+          </div>
+          <div class="innercontent">
+            <div><a href="#" v-on:mousedown="confirmNextPage" v-if="list.nl.length==1" style="margin-bottom: 5px">Confirm
+              Pagination Setup</a>
+            </div>
+            <div><a href="#" v-on:mousedown="cancelNextPage">Cancel Pagination Setup</a></div>
+          </div>
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>
-
   </div>
   </div>
 </template>
 </template>
 
 
@@ -445,6 +486,9 @@ export default {
     optionMode: 0,
     optionMode: 0,
     optionValue: "",
     optionValue: "",
     mode: 0, //记录删除字段模式
     mode: 0, //记录删除字段模式
+    nextPage: 0, //是否设置翻页操作
+    lastAction: "collectData", //记录上一次的操作
+    global: global,
   },
   },
   mounted() {
   mounted() {
     this.$nextTick(() => {
     this.$nextTick(() => {
@@ -515,18 +559,35 @@ export default {
       this.selectedDescendents = false;
       this.selectedDescendents = false;
       this.selectStatus = false;
       this.selectStatus = false;
       this.nowPath = "";
       this.nowPath = "";
+      console.log("initialized")
     },
     },
     confirmCollectSingle: function () { //单元素确认采集
     confirmCollectSingle: function () { //单元素确认采集
       collectSingle();
       collectSingle();
       clearEl();
       clearEl();
+      this.nextPage = 1;
+      this.lastAction = "collectData";
     },
     },
     confirmCollectMulti: function () { //无规律多元素确认采集
     confirmCollectMulti: function () { //无规律多元素确认采集
       collectMultiNoPattern();
       collectMultiNoPattern();
       clearEl();
       clearEl();
+      this.nextPage = 1;
+      this.lastAction = "collectData";
     },
     },
     confirmCollectMultiAndDescendents: function () { //有规律多元素确认采集
     confirmCollectMultiAndDescendents: function () { //有规律多元素确认采集
       collectMultiWithPattern();
       collectMultiWithPattern();
       clearEl();
       clearEl();
+      this.nextPage = 1;
+      this.lastAction = "collectDataWithLoop";
+    },
+    setNextPage: function () { //设置下一页元素
+      this.page = 3;
+    },
+    confirmNextPage: function () { //确认下一页元素
+      this.loopClickSingleElement("nextPageFromIndexPage");
+    },
+    cancelNextPage: function () { //取消下一页元素
+      this.cancel();
+      this.nextPage = 1; //保留下一页元素设置
     },
     },
     deleteSingleLine: function (event) { //删除单行元素
     deleteSingleLine: function (event) { //删除单行元素
       let at = new Date().getTime()
       let at = new Date().getTime()
@@ -574,6 +635,8 @@ export default {
       await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
       await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
       // global.nodeList[0]["node"].click(); //点击元素
       // global.nodeList[0]["node"].click(); //点击元素
       clearEl();
       clearEl();
+      this.nextPage = 0;
+      this.lastAction = "clickElement";
     },
     },
     changeSelect: function () {
     changeSelect: function () {
       this.page = 2;
       this.page = 2;
@@ -607,8 +670,9 @@ export default {
           alert("Switch failed, may fail when actually executed, please note.");
           alert("Switch failed, may fail when actually executed, please note.");
         }
         }
       }
       }
-
       clearEl();
       clearEl();
+      this.nextPage = 0;
+      this.lastAction = "changeSelect";
     },
     },
     handleSelectChange: function () {
     handleSelectChange: function () {
       console.log(this.optionMode, this.optionValue);
       console.log(this.optionMode, this.optionValue);
@@ -625,19 +689,29 @@ export default {
     mouseMove: function () {
     mouseMove: function () {
       sendMouseMove();
       sendMouseMove();
       clearEl();
       clearEl();
+      this.nextPage = 0;
+      this.lastAction = "mouseMove";
     },
     },
     loopMouseMove: function () {
     loopMouseMove: function () {
       sendLoopMouseMove();
       sendLoopMouseMove();
       clearEl();
       clearEl();
+      this.nextPage = 0;
+      this.lastAction = "loopMouseMove";
     },
     },
-    loopClickSingleElement: async function () { //循环点击单个元素
-      sendLoopClickSingle(this.tname()); //识别下一页,循环点击单个元素和点击多个元素
+    loopClickSingleElement: async function (type = "") { //循环点击单个元素
+      let name = this.tname();
+      if (type == "nextPageFromIndexPage") {
+        name = "nextPageFromIndexPage"
+      }
+      sendLoopClickSingle(name); //识别下一页,循环点击单个元素和点击多个元素
       // if (this.tname() != "下一页元素") { //下一页元素不进行点击操作
       // if (this.tname() != "下一页元素") { //下一页元素不进行点击操作
       global.nodeList[0]["node"].focus(); //获得元素焦点
       global.nodeList[0]["node"].focus(); //获得元素焦点
       await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
       await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
       // global.nodeList[0]["node"].click(); //点击元素
       // global.nodeList[0]["node"].click(); //点击元素
       // }
       // }
       clearEl();
       clearEl();
+      this.nextPage = 0;
+      this.lastAction = "clickElementWithLoop";
     },
     },
     loopClickEveryElement: async function () { //循环点击每个元素
     loopClickEveryElement: async function () { //循环点击每个元素
       sendLoopClickEvery(); //识别下一页,循环点击单个元素和点击多个元素
       sendLoopClickEvery(); //识别下一页,循环点击单个元素和点击多个元素
@@ -645,6 +719,8 @@ export default {
       await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
       await new Promise(resolve => setTimeout(resolve, 500)); //因为nodejs点击后又会把当前元素加入到列表中,所以这里需要等待一下再清空
       // global.nodeList[0]["node"].click(); //点击元素
       // global.nodeList[0]["node"].click(); //点击元素
       clearEl();
       clearEl();
+      this.nextPage = 0;
+      this.lastAction = "clickEveryElementWithLoop";
     },
     },
     setInput: function (batch = false) { //输入文字
     setInput: function (batch = false) { //输入文字
       this.batch = batch;
       this.batch = batch;
@@ -677,7 +753,8 @@ export default {
       this.selectStatus = true;
       this.selectStatus = true;
       clearReady();
       clearReady();
     },
     },
-    getCurrentTitle: function () { //获取当前页面的Title
+    getCurrentTitle: function () {
+      //获取当前页面的Title
       // 获取文档中所有元素
       // 获取文档中所有元素
       // const elements = document.querySelectorAll('*');
       // const elements = document.querySelectorAll('*');
       // global.nodeList.push(elements[0]); //将页面第一个元素放入列表中
       // global.nodeList.push(elements[0]); //将页面第一个元素放入列表中

+ 14 - 5
Extension/manifest_v3/src/content-scripts/trail.js

@@ -62,6 +62,8 @@ export function trial(evt) {
                         let realXPath = parent_xpath + xpath;
                         let realXPath = parent_xpath + xpath;
                         xpaths.push(realXPath);
                         xpaths.push(realXPath);
                     }
                     }
+                } else {
+                    xpaths.push(xpath);
                 }
                 }
                 for (let j = 0; j < xpaths.length; j++) {
                 for (let j = 0; j < xpaths.length; j++) {
                     let xpath = xpaths[j];
                     let xpath = xpaths[j];
@@ -119,11 +121,18 @@ export function trial(evt) {
                 } else if (loopType == 1) {
                 } else if (loopType == 1) {
                     let elementList = document.evaluate(parameters.xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
                     let elementList = document.evaluate(parameters.xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
                     let element = elementList.snapshotItem(0);
                     let element = elementList.snapshotItem(0);
-                    if (element != null) {
-                        clearEl(true);
-                        addEl(null, element);
-                        if (elementList.snapshotLength > 1) {
-                            selectAllElements();
+                    // if (element != null) {
+                    //     clearEl(true);
+                    //     addEl(null, element);
+                    //     if (elementList.snapshotLength > 1) {
+                    //         selectAllElements();
+                    //     }
+                    // }
+                    clearEl(true);
+                    for (let i = 0; i < elementList.snapshotLength; i++) {
+                        let element = elementList.snapshotItem(i);
+                        if (element != null) {
+                            addEl(null, element);
                         }
                         }
                     }
                     }
                 } else if (loopType == 2) {
                 } else if (loopType == 2) {

+ 12 - 0
Extension/manifest_v3/src/style/toolkit.css

@@ -59,6 +59,18 @@
     padding-left: 5px !important;
     padding-left: 5px !important;
 }
 }
 
 
+.nextPage a{
+    color: darkviolet!important;
+}
+
+.nextPage a:hover{
+    color: blue!important;
+}
+
+.nextPage span{
+    color: darkviolet!important;
+}
+
 .tooltips button {
 .tooltips button {
     margin-top: 7px !important;
     margin-top: 7px !important;
     font-size: 13px;
     font-size: 13px;

+ 7 - 6
Readme.md

@@ -49,17 +49,18 @@ More features please scroll to the bottom of this page to view.
 
 
 Refer to the [Releases Page](https://github.com/NaiboWang/EasySpider/releases) to download the latest version of EasySpider.
 Refer to the [Releases Page](https://github.com/NaiboWang/EasySpider/releases) to download the latest version of EasySpider.
 
 
-<!-- ## 支持作者/Support Author
+## 支持作者/Support Author
 
 
 易采集EasySpider是一款完全免费无广告的开源软件,软件开发和维护全靠作者用爱发电,因此您可以选择支持作者让作者有更多的热情和精力维护此软件,或者您使用了此软件进行了盈利,欢迎您通过下面的方式支持作者:
 易采集EasySpider是一款完全免费无广告的开源软件,软件开发和维护全靠作者用爱发电,因此您可以选择支持作者让作者有更多的热情和精力维护此软件,或者您使用了此软件进行了盈利,欢迎您通过下面的方式支持作者:
 
 
-1. 支付宝账号:[email protected],也可以扫描下方二维码。
-2. 微信收款:扫描下方二维码。
-3. PayPal账号:naibowang,也可以扫描下方二维码。
+1. Github Sponsor:直接点击右侧**Sponsor**按钮赞助。
+2. 支付宝账号:[email protected],也可以扫描下方二维码。
+3. 微信收款:扫描下方二维码。
+4. PayPal账号:naibowang,也可以扫描下方二维码。
 
 
-Support author at paypal if you like this software, or use it to make profit: naibowang
+You can support the author by clicking the **Sponsor** button at right side or pay via paypal: naibowang.
 
 
-![QRCodes](media/QRCODES.png) -->
+![QRCodes](media/QRCODES.png)
 
 
 
 
 
 

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно