Parcourir la source

Bug fix

pull/254/head
naibo il y a 9 mois
Parent
révision
18333a40ec
5 fichiers modifiés avec 451 ajouts et 442 suppressions
  1. +242
    -237
      ElectronJS/src/taskGrid/FlowChart.css
  2. +97
    -97
      ElectronJS/src/taskGrid/FlowChart.html
  3. +98
    -98
      ElectronJS/src/taskGrid/FlowChart_CN.html
  4. +8
    -8
      ElectronJS/src/taskGrid/logic.js
  5. +6
    -2
      Extension/manifest_v3/src/content-scripts/toolkit.vue

+ 242
- 237
ElectronJS/src/taskGrid/FlowChart.css Voir le fichier

@ -1,237 +1,242 @@
* {
margin: 0;
padding: 0;
font-size: 17px!important;
}
.modal-body label{
margin-top: 10px;
}
#contextMenu {
position: absolute;
background-color: white;
padding: 3px!important;
text-align: center;
border: 1px solid darkblue;
border-radius: 3px;
/*width: 120px;*/
}
#contextMenu div{
height: 30px;
padding-top: 2px;
}
#contextMenu div:hover {
background-color: rgba(211,211,211,0.4) !important;
cursor: pointer;
}
label{
margin-left: 2px;
}
div.node {
height: 45px;
width: 180px;
border-radius: 7px;
/*border: skyblue solid;*/
border: #007bff solid;
border-color: transparent;
/*background: rgb(73, 156, 189);*/
background: rgb(10, 120, 200);
color: white;
text-align: center;
padding: 5px;
margin: 10px auto;
}
.arrow {
margin: 10px auto;
text-align: center;
font-size: 23px!important;
color: black;
}
.arrow:hover {
background-color: deepskyblue!important;
cursor: pointer;
color: white;
}
.branchAdd {
margin: 10px auto;
text-align: center;
font-size: 18px!important;
color: black;
}
.branchAdd:hover {
background-color: deepskyblue;
cursor: pointer;
color: white;
}
div.node:hover {
cursor: pointer;
background: navy;
}
.loop {
/*border: skyblue solid;*/
border: rgb(10,120,200) solid;
border-color: deepskyblue;
text-align: center;
padding: 5px;
width: 90%;
min-width: 150px;
overflow: auto;
margin: 10px auto;
border-radius: 7px;
}
.options {
height: 35px;
}
.judge {
/* display: flex; */
text-align: center;
padding: 5px;
width: 100%;
min-width: 150px;
margin: 10px auto;
justify-content: center;
border-radius: 7px;
}
.branch {
display: inline-block;
margin: 5px;
border: deepskyblue solid;
text-align: center;
padding: 5px;
width: 300px;
min-width: 150px;
margin: 10px;
border-radius: 7px;
}
.sequence {
display: block;
}
.toolbox button {
margin-top: 5px;
margin-left: 3px;
margin-bottom: 5px;
width: 80%;
font-size: 15px!important;
}
.Modify {
margin: 20px;
}
.Modify input {
font-size: 17px!important;
}
.elements {
font-size: 17px!important;
margin: 10px 0;
}
.elements p {
margin: 5px 0;
}
.elements input[type=checkbox] {
width: 20px;
height: 20px;
vertical-align: sub;
margin-right: 5px;
}
.elements textarea {
min-height: 100px;
}
.elements label {
font-size: 17px!important;
margin: 10px 0;
}
/* th,
td,
tr {
height: 30px;
width: 100px;
font-size: 13px!important;
overflow: hidden;
border: 1px solid rgb(78, 78, 78);
padding-left: 2px;
}
table {
table-layout: fixed;
word-break: break-all;
word-wrap: break-word;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
} */
.toolkitcontain {
border: 1px solid #cdd!important;
width: 100%;
/* 上面的宽度设定很重要 */
height: 214px;
overflow: auto;
margin-top: 10px;
position: relative;
}
.toolkitcontain table {
table-layout: fixed;
word-break: break-all;
word-wrap: break-word;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
.toolkitcontain th,
.toolkitcontain td,
.toolkitcontain tr {
border: 1px solid rgb(78, 78, 78);
height: 30px;
width: 100px;
text-align: center;
font-weight: normal!important;
overflow: hidden;
font-size: 13px!important;
padding-left: 1px;
-webkit-user-select: none;
}
.toolkitcontain .toolkittb2 {
position: sticky;
top: 0px;
margin-bottom: 0px;
/*background-color: azure;*/
background-color: aliceblue;
z-index: 1000;
}
.toolkitcontain .toolkittb4 {
position: absolute;
}
.toolkitcontain a {
font-size: 13px!important;
cursor: pointer;
color: blue;
}
* {
margin: 0;
padding: 0;
font-size: 17px !important;
}
input, textarea {
spellcheck: false;
}
.modal-body label {
margin-top: 10px;
}
#contextMenu {
position: absolute;
background-color: white;
padding: 3px !important;
text-align: center;
border: 1px solid darkblue;
border-radius: 3px;
/*width: 120px;*/
}
#contextMenu div {
height: 30px;
padding-top: 2px;
}
#contextMenu div:hover {
background-color: rgba(211, 211, 211, 0.4) !important;
cursor: pointer;
}
label {
margin-left: 2px;
}
div.node {
height: 45px;
width: 180px;
border-radius: 7px;
/*border: skyblue solid;*/
border: #007bff solid;
border-color: transparent;
/*background: rgb(73, 156, 189);*/
background: rgb(10, 120, 200);
color: white;
text-align: center;
padding: 5px;
margin: 10px auto;
}
.arrow {
margin: 10px auto;
text-align: center;
font-size: 23px !important;
color: black;
}
.arrow:hover {
background-color: deepskyblue !important;
cursor: pointer;
color: white;
}
.branchAdd {
margin: 10px auto;
text-align: center;
font-size: 18px !important;
color: black;
}
.branchAdd:hover {
background-color: deepskyblue;
cursor: pointer;
color: white;
}
div.node:hover {
cursor: pointer;
background: navy;
}
.loop {
/*border: skyblue solid;*/
border: rgb(10, 120, 200) solid;
border-color: deepskyblue;
text-align: center;
padding: 5px;
width: 90%;
min-width: 150px;
overflow: auto;
margin: 10px auto;
border-radius: 7px;
}
.options {
height: 35px;
}
.judge {
/* display: flex; */
text-align: center;
padding: 5px;
width: 100%;
min-width: 150px;
margin: 10px auto;
justify-content: center;
border-radius: 7px;
}
.branch {
display: inline-block;
margin: 5px;
border: deepskyblue solid;
text-align: center;
padding: 5px;
width: 300px;
min-width: 150px;
margin: 10px;
border-radius: 7px;
}
.sequence {
display: block;
}
.toolbox button {
margin-top: 5px;
margin-left: 3px;
margin-bottom: 5px;
width: 80%;
font-size: 15px !important;
}
.Modify {
margin: 20px;
}
.Modify input {
font-size: 17px !important;
}
.elements {
font-size: 17px !important;
margin: 10px 0;
}
.elements p {
margin: 5px 0;
}
.elements input[type=checkbox] {
width: 20px;
height: 20px;
vertical-align: sub;
margin-right: 5px;
}
.elements textarea {
min-height: 100px;
}
.elements label {
font-size: 17px !important;
margin: 10px 0;
}
/* th,
td,
tr {
height: 30px;
width: 100px;
font-size: 13px!important;
overflow: hidden;
border: 1px solid rgb(78, 78, 78);
padding-left: 2px;
}
table {
table-layout: fixed;
word-break: break-all;
word-wrap: break-word;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
} */
.toolkitcontain {
border: 1px solid #cdd !important;
width: 100%;
/* 上面的宽度设定很重要 */
height: 214px;
overflow: auto;
margin-top: 10px;
position: relative;
}
.toolkitcontain table {
table-layout: fixed;
word-break: break-all;
word-wrap: break-word;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 100%;
}
.toolkitcontain th,
.toolkitcontain td,
.toolkitcontain tr {
border: 1px solid rgb(78, 78, 78);
height: 30px;
width: 100px;
text-align: center;
font-weight: normal !important;
overflow: hidden;
font-size: 13px !important;
padding-left: 1px;
-webkit-user-select: none;
}
.toolkitcontain .toolkittb2 {
position: sticky;
top: 0px;
margin-bottom: 0px;
/*background-color: azure;*/
background-color: aliceblue;
z-index: 1000;
}
.toolkitcontain .toolkittb4 {
position: absolute;
}
.toolkitcontain a {
font-size: 13px !important;
cursor: pointer;
color: blue;
}

+ 97
- 97
ElectronJS/src/taskGrid/FlowChart.html Voir le fichier

@ -67,7 +67,7 @@
</div>
<div style="margin-top:20px;border: solid navy;height:850px;overflow: auto;margin-left:10px;margin-right:10px;width:30%;float:right;min-width:300px">
<!-- <div style="display: inline-block;border-bottom:solid 2px;width:100%">
<input style="float:left;margin-left:10px;margin-top:10px;margin-bottom:10px" type="button" class="btn-primary" value="保存服务"></input>
<input spellcheck=false style="float:left;margin-left:10px;margin-top:10px;margin-bottom:10px" type="button" class="btn-primary" value="保存服务"></input>
</div> -->
<div class="Modify" id="app">
<div class="modal fade" id="myModal_XPath" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
@ -80,7 +80,7 @@
<div class="modal-body">
<label>The following are alternative XPath expressions, in addition to the default generated XPath, that can all locate the same element (although not entirely accurate, they may also locate other elements besides the intended one, so they are provided here for reference only). </label>
<label>Each line contains an XPath expression (you can use the pre-installed <i>XPath Helper</i> extension for debugging):</label>
<textarea id="otherXPaths" onkeydown="inputDelete(event)" class="form-control" rows="4">{{XPaths}}</textarea>
<textarea spellcheck=false id="otherXPaths" onkeydown="inputDelete(event)" class="form-control" rows="4">{{XPaths}}</textarea>
<div>
<img src="../img/XPather_helper.png" style="width:50%;height:50%; margin: 10px auto"></div>
</div>
@ -93,24 +93,24 @@
<div>
<label>Tip: Hover over the smiley face to view hints, <b>double-click</b> on an action in the flowchart to test run, <b>right-click</b> on an action to see more options.</label>
<label>Option Name:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='list.nl[index.nowNodeIndex]["title"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='list.nl[index.nowNodeIndex]["title"]'></input>
</div>
<!-- 下面是10种不同类型操作选项的不同的配置页面 -->
<div class="elements" v-if="nodeType==1">
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use link inside the Loop</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use link inside the Loop</p>
</div>
<div v-if='!useLoop'>
<!-- <label>url:</label>-->
<!-- <input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["url"]'></input>-->
<!-- <input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["url"]'></input>-->
<label v-if='nowNode["parameters"]["url"]!="about:blank"'>Links (one link per line, the entire workflow will be executed as many times as there are lines of links):</label>
<label v-else>Link (Only one link can be put here)</label>
<textarea v-if='nowNode["parameters"]["url"]!="about:blank"' onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["links"]'></textarea>
<input v-else onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["links"]'></input>
<textarea spellcheck=false v-if='nowNode["parameters"]["url"]!="about:blank"' onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["links"]'></textarea>
<input spellcheck=false v-else onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["links"]'></input>
</div>
<label>Maximum wait time for page load (in seconds): </label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['maxWaitTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['maxWaitTime']" type="number" required></input>
<label>After executed, whether scroll down:</label>
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
<option :value = 0>No scrolling</option>
@ -119,9 +119,9 @@
<option :value = 3>Keep scrolling until the page data does not change</option>
</select>
<label>Scroll Times (the wait time after scrolling <b>ineffective</b> when the scrolling type is set to <b>no scrolling</b>):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>Wait time after scrolling (in seconds): </label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<p style="margin-top: 10px">
<a class="btn btn-primary" data-toggle="collapse" href="#collapseOpenPage" role="button" aria-expanded="false" aria-controls="collapseExample">
Click here to expand/collapse advanced operations
@ -133,25 +133,25 @@
<p style="margin-bottom: 20px;color:white"><a class="btn btn-primary" @click="getCookies">
Click here to get cookies of current page
</a></p>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='key=value, one pair per line' v-model='nowNode["parameters"]["cookies"]' id="pageCookies" style="font-size: 14px!important;"></textarea>
</div>
</div>
</div>
<div class="elements" v-if="nodeType==2">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Element is inside iframe</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Element is inside iframe</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use element located by xpath relative to the loop</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use element located by xpath relative to the loop</p>
</div>
<div>
<label>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></label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode['parameters']['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">Click here to view other equivalent XPath expressions</button></p>
</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>
<input spellcheck=false 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>
@ -170,9 +170,9 @@
<option :value = 3>Keep scrolling until the page data does not change</option>
</select>
<label>Scroll Times:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>Wait time after scrolling (in seconds):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<label>Way to handle pop-up windows after clicking:</label>
<p><select v-model='nowNode["parameters"]["alertHandleType"]' class="form-control">
<option :value = 0>No pop-up window</option>
@ -187,14 +187,14 @@
<div :class="{collapse: true, 'show': nowNode['parameters']['beforeJS'].length!=0 || nowNode['parameters']['afterJS'].length!=0}" id="collapseExample">
<div>
<label>Execute a JavaScript script <strong>before</strong> clicking on this element:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].innerText = arguments[0].innerText.replace("United States","US"). This code replaces occurrences of "United States" with "US" in the text of the element. Subsequently, when extracting data, you will obtain the replaced value.' v-model='nowNode["parameters"]["beforeJS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<label>Execute a JavaScript script <strong>after</strong> clicking on this element: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].click(). This code simulates a click on the element.' v-model='nowNode["parameters"]["afterJS"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].click(). This code simulates a click on the element.' v-model='nowNode["parameters"]["afterJS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["afterJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["afterJSWaitTime"]'></input>
</div>
</div>
@ -206,8 +206,8 @@
<p>
<button class="btn btn-primary" v-on:mousedown= 'addPara'>New Field</button>
</p>
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["clear"]'></input>Clear other field existing values before extracting</p>
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["newLine"]'></input>This operation will generate a new row of data <span style="font-size: 30px!important;" title="If unchecked, it will use the same row of data as the previous operation. If checked, it will generate a new row of data."></span> </p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["clear"]'></input>Clear other field existing values before extracting</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["newLine"]'></input>This operation will generate a new row of data <span style="font-size: 30px!important;" title="If unchecked, it will use the same row of data as the previous operation. If checked, it will generate a new row of data."></span> </p>
<div class="toolkitcontain">
<table class="toolkittb2" cellspacing="0">
<tbody>
@ -219,7 +219,7 @@
<table class="toolkittb4" cellspacing="0">
<tbody>
<tr v-for="i in paras.parameters.length">
<td style="padding-left:0px"><input onkeydown="inputDelete(event)" style='padding-left:2px;font-size:13px!important;height:100%' v-model='paras.parameters[i-1]["name"]'></input>
<td style="padding-left:0px"><input spellcheck=false onkeydown="inputDelete(event)" style='padding-left:2px;font-size:13px!important;height:100%' v-model='paras.parameters[i-1]["name"]'></input>
</td>
<td style="width:200px">{{paras.parameters[i-1]["exampleValues"][0]["value"]}}</td>
<td>
@ -234,10 +234,10 @@
<div style="font-size: 13px;" v-if="paraIndex<paras.parameters.length">
<p>Current parameter name (Clicking on the "Modify" option of the field toggles the parameters)</p>
<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 v-if='!paras.parameters[paraIndex]["relative"]'><input onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["iframe"]'></input>Element is inside iframe</p>
<p v-if="nowNode['isInLoop']"><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["relative"]'></input>Use relative XPath</p>
<p v-if='!paras.parameters[paraIndex]["relative"]'><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["iframe"]'></input>Element is inside iframe</p>
<p>XPATH (Field["FieldName"] and eval("your code") can be used in any XPATHS): <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"]' 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>
<textarea spellcheck=false 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">
@ -248,14 +248,14 @@
<div>
<div><a href="#" v-on:mousedown="trailPara(paraIndex)" style="text-decoration: none">Trail Run</a></div>
<label>Execute a JavaScript script <strong>before</strong> extracting data from this element: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].innerText = arguments[0].innerText.replace("United States","US"). This code replaces occurrences of "United States" with "US" in the text of the element. Subsequently, when extracting data, you will obtain the replaced value.' v-model='paras.parameters[paraIndex]["beforeJS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["beforeJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["beforeJSWaitTime"]'></input>
<label>Execute a JavaScript script <strong>after</strong> extracting data from this element: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].click(). This code simulates a click on the element.' v-model='paras.parameters[paraIndex]["afterJS"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].click(). This code simulates a click on the element.' v-model='paras.parameters[paraIndex]["afterJS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["afterJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["afterJSWaitTime"]'></input>
</div>
</div>
<label>Parameter type conversion (for Excel and Database):</label>
@ -272,7 +272,7 @@
<option value = "bigInt">Large Integer (more than 9 digits)</option>
</select>
<label>Default value when cannot find this element:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["default"]'></textarea>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["default"]'></textarea>
<label>Extract Type</label>
<select v-model='paras.parameters[paraIndex]["contentType"]' class="form-control">
<option :value = 0>Text (include child element)</option>
@ -293,14 +293,14 @@
</select>
<div v-if='paras.parameters[paraIndex]["contentType"] == 14'>
<label>Attribute Name:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["JS"]' placeholder="Attribute names, such as href to represent the href attribute of the current element, that is, the link address."></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["JS"]' placeholder="Attribute names, such as href to represent the href attribute of the current element, that is, the link address."></input>
</div>
<div v-else-if='paras.parameters[paraIndex]["contentType"] == 9 || paras.parameters[paraIndex]["contentType"] >= 12'>
<label>Code (Use Field["FieldName"] to input the lastest value of a field): </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='The element should be represented by arguments[0]. Here is an example: return arguments[0].innerText + "US Dollar". This code extracts the innerText of the element and appends "US Dollar" to it.' v-model='paras.parameters[paraIndex]["JS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["JSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["JSWaitTime"]'></input>
</div>
<label>Node Type</label>
<select v-model='paras.parameters[paraIndex]["nodeType"]' class="form-control">
@ -328,30 +328,30 @@
<option :value = 0>No</option>
</select>
<label>Parameter Description:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" style="min-height: 60px" v-model='paras.parameters[paraIndex]["desc"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" style="min-height: 60px" v-model='paras.parameters[paraIndex]["desc"]'></textarea>
</div>
</div>
<div class="elements" v-if="nodeType==4">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Element is inside iframe</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Element is inside iframe</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use text from the loop (If unchecked, the text entered each time will be the text from the "Input Value" text box below. If checked, it will use the text set within the loop.)</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use text from the loop (If unchecked, the text entered each time will be the text from the "Input Value" text box below. If checked, it will use the text set within the loop.)</p>
<p v-if="useLoop">
<label>Index value (0 represents using the entire current loop text. If greater than 0, it represents the text index value separated by "~" within the current loop. For example, if the current loop text value is A~B, index value 1 represents inputting A, 2 represents inputting B, and 0 represents inputting A~B)</label>
<input onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input>
</p>
</div>
<div v-if='!useLoop'>
<label>Input value (Use Field["FieldName"] to input the latest extracted/returned value of a field or custom operation. Use &lt;enter&gt; or &lt;ENTER&gt; to simulate pressing the Enter key):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["value"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["value"]'></input>
</div>
<label>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></label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode.parameters['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="#inputAdvanced" role="button" aria-expanded="false" aria-controls="collapseExample">
@ -361,20 +361,20 @@
<div :class="{collapse: true, 'show': nowNode['parameters']['beforeJS'].length!=0 || nowNode['parameters']['afterJS'].length!=0}" id="inputAdvanced">
<div>
<label>Execute JavaScript script on this element <b>before</b> entering text into it: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].innerText = arguments[0].innerText.replace("United States","US"). This code replaces occurrences of "United States" with "US" in the text of the element. Subsequently, when extracting data, you will obtain the replaced value.' v-model='nowNode["parameters"]["beforeJS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<label>Execute JavaScript script on this element <b>after</b> entering text into it: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].click(). This code simulates a click on the element.' v-model='nowNode["parameters"]["afterJS"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='The element should be represented by arguments[0]. Here is an example JavaScript code: arguments[0].click(). This code simulates a click on the element.' v-model='nowNode["parameters"]["afterJS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["afterJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["afterJSWaitTime"]'></input>
</div>
</div>
</div>
<div class="elements" v-if="nodeType==5">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Action is inside iframe</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Action is inside iframe</p>
<label>Action Mode</label>
<select v-model='codeMode' class="form-control" @change="handleCodeModeChange">
<option :value = 0>Execute JavaScript script (Start with "return " if you want to get return value)</option>
@ -390,7 +390,7 @@
</select>
<div v-if='nowNode["parameters"]["codeMode"] < 3 || nowNode["parameters"]["codeMode"] >= 5 && nowNode["parameters"]["codeMode"] <=6'>
<label>Code (Use Field["FieldName"] to input the lastest value of a field): </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["code"]' placeholder="Please input a JavaScript command or a system command. For example, document.body.innerText = '1' is an example of a JavaScript command, and python D:/test.py is an example of a system command. If you choose to execute a JavaScript script for the current iteration, you can represent the element of the current iteration using arguments[0]. For instance, arguments[0].style.color = 'blue' sets the color of the element in the current iteration to blue."></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["code"]' placeholder="Please input a JavaScript command or a system command. For example, document.body.innerText = '1' is an example of a JavaScript command, and python D:/test.py is an example of a system command. If you choose to execute a JavaScript script for the current iteration, you can represent the element of the current iteration using arguments[0]. For instance, arguments[0].style.color = 'blue' sets the color of the element in the current iteration to blue."></textarea>
<pre class="form-control" style="background: white; margin-top: 20px; min-height: 200px; font-size: 15px!important; word-wrap: break-word; white-space: pre-wrap; border-radius: 0; border: 1px solid" disabled v-if='nowNode["parameters"]["codeMode"] == 5'>Please read the instructions first and then write the specific code in the input box above (not in this box). To execute a large amount of code, you can simply write "outside:myCode.py" and the program will read and execute the code within myCode.py under the EasySpider directory.
Be aware that statements containing exec and eval operations and XPath cannot be tested on the current page, and can only be run when they are actually called upon in a task.
This option is an advanced feature that allows direct manipulation of the running browser using Python code. You can also customize variables in the entire execution environment and perform operations such as modifying and assigning values. Here are some examples:
@ -452,7 +452,7 @@ Please note that this feature does not support assigning values to variables. In
</select>
</p>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
</div>
<div v-if='nowNode["parameters"]["codeMode"] == 7'>
<label>This operation can pause program execution, such as when a captcha box appears, and it will not continue until you manually press and hold the pause/continue shortcut key (default: key p).</label>
@ -463,35 +463,35 @@ Please note that this feature does not support assigning values to variables. In
<div v-if='nowNode["parameters"]["codeMode"] == 9'>
<label>This operation can send emails, for example, to notify by email when a web scraping task is completed.</label>
<label>SMTP email server host:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["host"]' placeholder="e.g., smtp.gmail.com"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["host"]' placeholder="e.g., smtp.gmail.com"></input>
<label>Email server port:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["port"]' placeholder="e.g., 465"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["port"]' placeholder="e.g., 465"></input>
<label>Sender email username:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["username"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["username"]'></input>
<label>Sender email password (Be careful not to leak the task file if a password is set!):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["password"]' placeholder="Most email servers use authorization codes, not the original password"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["password"]' placeholder="Most email servers use authorization codes, not the original password"></input>
<label>Recipient email address:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["to"]' placeholder="Separate multiple recipients with commas"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["to"]' placeholder="Separate multiple recipients with commas"></input>
<label>Email subject:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["subject"]' placeholder="Write the email subject here"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["subject"]' placeholder="Write the email subject here"></input>
<label>Email content:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["emailConfig"]["content"]' placeholder="Write the email content here"></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["emailConfig"]["content"]' placeholder="Write the email content here"></textarea>
</div>
</div>
<div class="elements" v-if="nodeType==6">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Element is inside iframe</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Element is inside iframe</p>
<div v-if="nowNode['isInLoop']">
<!-- Display this element only if inside a loop and the loop contains fixed text -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use index value from within the loop (if unchecked, the setting will be the value of the "Set Value" text box below. If checked, it will use the index value set within the loop's dropdown box.)</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use index value from within the loop (if unchecked, the setting will be the value of the "Set Value" text box below. If checked, it will use the index value set within the loop's dropdown box.)</p>
<p v-if="useLoop">
<label>Relative index value of the loop value (0 represents using the entire current loop's text. If greater than 0, it represents the value of the text separated by "~" within the current loop. For example, if the current loop's text value is 2~3 and you enter 2 here, it means taking the second item of the text, which is value 3, indicating setting the dropdown box to the third item.)</label>
<input onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input>
</p>
</div>
<label>XPath: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode['parameters']['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">Click here to view other equivalent XPath expressions</button></p>
<div v-if="!useLoop">
<p>Option switch Mode</p>
@ -502,19 +502,19 @@ Please note that this feature does not support assigning values to variables. In
<option :value = 3>Switch options by option text</option>
</select>
<p>Set value (not applicable for "Switch to the next option" mode)</p>
<input class="form-control" id="selectValue" v-model='nowNode["parameters"]["optionValue"]' autoFocus="autofocus" type="text"></input>
<input spellcheck=false class="form-control" id="selectValue" v-model='nowNode["parameters"]["optionValue"]' autoFocus="autofocus" type="text"></input>
</div>
</div>
<div class="elements" v-if="nodeType==7">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Element is inside iframe</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Element is inside iframe</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use element located by xpath relative to the loop</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>Use element located by xpath relative to the loop</p>
</div>
<div>
<label>XPath: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode['parameters']['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">Click here to view other equivalent XPath expressions</button></p>
</div>
@ -522,7 +522,7 @@ Please note that this feature does not support assigning values to variables. In
</div>
<div class="elements" v-if="nodeType==8">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Operation is in iframe</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Operation is in iframe</p>
<!-- 循环选项 -->
<label>Loop Type:</label>
<select v-model='loopType' class="form-control" @change="handleLoopTypeChange">
@ -537,20 +537,20 @@ Please note that this feature does not support assigning values to variables. In
</select>
<div v-if='parseInt(loopType) < 2'>
<label>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></label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]' placeholder="You cannot use expressions like @href or text() within loops in XPath. You can only locate elements, but cannot fetch attribute values. Declaratives like @href and text() are only supported in data extraction operations. Moreover, it is not recommended to use them. Instead, it's suggested choosing the node type and type of the content to collect directly within data extraction operations."></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]' placeholder="You cannot use expressions like @href or text() within loops in XPath. You can only locate elements, but cannot fetch attribute values. Declaratives like @href and text() are only supported in data extraction operations. Moreover, it is not recommended to use them. Instead, it's suggested choosing the node type and type of the content to collect directly within data extraction operations."></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode.parameters['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">(Testing feature) Click here to view other possible XPath expressions</button></p>
</div>
<div v-if='parseInt(loopType) == 2'>
<label>XPath List:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["pathList"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["pathList"]'></textarea>
</div>
<div v-else-if='parseInt(loopType) < 5'>
<label>Content List (Use Field["FieldName"] to input the lastest value of a field):</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" placeholder="One text/URL per line. Each line is A text/URL, and the text is divided by ~, that is, if the value of A line is A~B, the index value can be set to 1 for A, 2 for B, and 0 for A~B in the input text operation." v-model='nowNode["parameters"]["textList"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" placeholder="One text/URL per line. Each line is A text/URL, and the text is divided by ~, that is, if the value of A line is A~B, the index value can be set to 1 for A, 2 for B, and 0 for A~B in the input text operation." v-model='nowNode["parameters"]["textList"]'></textarea>
</div>
<div v-else-if='parseInt(loopType) < 8'>
<label>Code (Use Field["FieldName"] to input the lastest value of a field):</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="Continue the loop if the command return value is greater than 0 or evaluates to true; otherwise, stop the loop. For example, return document.body.scrollWidth > 1000 is an example of a JavaScript command return value, and python D:/test.py is an example of a system command return value."></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="Continue the loop if the command return value is greater than 0 or evaluates to true; otherwise, stop the loop. For example, return document.body.scrollWidth > 1000 is an example of a JavaScript command return value, and python D:/test.py is an example of a system command return value."></textarea>
<pre class="form-control" style="background: white; margin-top: 20px; min-height: 220px; font-size: 15px!important; word-wrap: break-word; white-space: pre-wrap; border-radius: 0; border: 1px solid" disabled v-if='parseInt(loopType) == 7'>Please read the instructions first and then write the specific code in the input box above (not in this box). To execute a large amount of code, you can simply write "outside:myCode.py" and the program will read and execute the code within myCode.py under the EasySpider directory.
Loop based on the expression value of Python code. Here are some examples:
1. Return relevant values of the current browser object. Use `self.browser` to refer to the current browser being operated. You can directly use Selenium's API to perform operations, such as `self.browser.find_element(By.CSS_SELECTOR, "body").text=="123"`, which checks whether the current page contains the text "123".
@ -560,14 +560,14 @@ Loop based on the expression value of Python code. Here are some examples:
If the expression returns a value greater than 0 or evaluates to True, the loop continues; otherwise, it stops.
</pre>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
</div>
<!-- 这里添加退出循环条件,找不到元素肯定退出循环 -->
<div v-if='parseInt(loopType) == 0'>
<label>Maximum number of loop iterations (0 represents an infinite loop until no more elements are found or no changes in page content are detected):</label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["exitCount"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["exitCount"]'></input>
<label>Exit the loop when the content of the following elements on the page does not change (effective when the count is 0. If it is a multi-layer nested iframe, it is recommended to write an XPath for an element that only exists within the iframe page you want to extract, such as /html/body/div[@class='LeftSide_menu']):</label>
<input onkeydown="inputDelete(event)" required class="form-control" type="text" v-model='nowNode["parameters"]["exitElement"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="text" v-model='nowNode["parameters"]["exitElement"]'></input>
</div>
<div id="breakAdvanced" v-if='nowNode["parameters"]["loopType"] < 5'>
@ -579,15 +579,15 @@ If the expression returns a value greater than 0 or evaluates to True, the loop
<option :value = 2>Operating system-level command</option>
</select>
<div>
<textarea style="margin-top: 10px" onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false style="margin-top: 10px" onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='Exit the loop directly if the command return value is less than or equal to 0 or evaluates to false. Example: return document.body.scrollWidth > 1000 or python D:/test.py, which are examples of JavaScript command and system command return values.' v-model='nowNode["parameters"]["breakCode"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["breakCodeWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["breakCodeWaitTime"]'></input>
</div>
</div>
</div>
<label>Waiting time in seconds after a history record rollback: </label>
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["historyWait"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["historyWait"]'></input>
<label>After executed, whether scroll down:</label>
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
<option :value = 0>No Scrolling</option>
@ -596,9 +596,9 @@ If the expression returns a value greater than 0 or evaluates to True, the loop
<option :value = 3>Keep scrolling until the page data does not change</option>
</select>
<label>Scroll Times:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>Wait time after scrolling (in seconds):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
</div>
<div class="elements" v-if="nodeType==9">
@ -607,7 +607,7 @@ If the expression returns a value greater than 0 or evaluates to True, the loop
<div class="elements" v-if="nodeType==10">
<label>The conditions are evaluated from left to right, which means if the condition in the leftmost branch is satisfied, the operations within that branch are executed. Otherwise, the condition in the next branch from left to right is evaluated, and so on. Clicking on a branch while designing tasks allows for <b>dynamic debugging</b> in the browser to verify if the branch satisfies the condition (not applicable to system commands and Python Eval operations). </label>
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Operation is in iframe</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>Operation is in iframe</p>
<label>Condition Type:</label>
<select v-model='TClass' class="form-control" @change="handleJudgeTypeChange">
<option :value = 0>No Condition</option>
@ -623,11 +623,11 @@ If the expression returns a value greater than 0 or evaluates to True, the loop
<div v-if='TClass > 0 && TClass < 5'>
<label>Text/Element XPath to Include: <span style="font-size: 30px!important;" title="Relative XPath syntax: starts with /, e.g., if the XPath of the loop item is /html/body/div[1], and you input /*[@id='tab-customer'], the final XPath will be: /html/body/div[1]/*[@id='tab-customer']"></span></label>
<textarea onkeydown="inputDelete(event)" required placeholder="If the current loop contains elements, input the xpath of the relative element (such as '/div[2]/div[1]/img', if written in relative path, it should be written as '/*//img', which means checking whether there exists an 'img' tag among all the descendant elements of the current loop item.)." class="form-control" rows="3" v-model='nowNode["parameters"]["value"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" required placeholder="If the current loop contains elements, input the xpath of the relative element (such as '/div[2]/div[1]/img', if written in relative path, it should be written as '/*//img', which means checking whether there exists an 'img' tag among all the descendant elements of the current loop item.)." class="form-control" rows="3" v-model='nowNode["parameters"]["value"]'></textarea>
</div>
<div v-else-if='TClass > 0 && TClass < 7 || TClass == 8'>
<label>Code/Script Content: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="If the return value is greater than 0 or true, the operations within this branch will be executed; otherwise, they will not be executed. For example: return document.body.scrollWidth > 1000 or python D:/test.py, representing examples of JS command and system command return values."></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="If the return value is greater than 0 or true, the operations within this branch will be executed; otherwise, they will not be executed. For example: return document.body.scrollWidth > 1000 or python D:/test.py, representing examples of JS command and system command return values."></textarea>
<pre class="form-control" style="background: white; margin-top: 20px; min-height: 200px; font-size: 15px!important; word-wrap: break-word!important; white-space: pre-wrap; border-radius: 0; border: 1px solid" disabled v-if='TClass == 8'>Please read the instructions first and then write the specific code in the input box above (not in this box). To execute a large amount of code, you can simply write "outside:myCode.py" and the program will read and execute the code within myCode.py under the EasySpider directory.
Use the expression value of Python code to determine whether a condition is satisfied. Here are some examples:
1. Return relevant values of the current browser object. Use `self.browser` to refer to the current browser being operated. You can directly use Selenium's API to perform operations, such as `self.browser.find_element(By.CSS_SELECTOR, "body").text=="123"`, which checks whether the current page contains the text "123".
@ -637,26 +637,26 @@ Use the expression value of Python code to determine whether a condition is sati
If the expression returns a value greater than 0 or evaluates to True, the operations within this branch will be executed; otherwise, they will be skipped.
</pre>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
</div>
<div v-else-if='TClass == 7'>
<label>Code/Script Content (<a href="https://github.com/NaiboWang/EasySpider/wiki/Example-of-JavaScript-instruction-for-the-current-iteration-in-a-conditional-statement" target="_blank">Click here</a> for more examples): </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="Enter the JS command for the current loop item. The loop item is represented by arguments[0]. If the return value is greater than 0 or true, the operations within this branch will be executed; otherwise, they will not be executed. For example: return arguments[0].innerText.length >= 5, which checks if the text length of the current loop item is greater than 5. Note that this is used in combination with element-related loop types (e.g., non-fixed element lists)."></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="Enter the JS command for the current loop item. The loop item is represented by arguments[0]. If the return value is greater than 0 or true, the operations within this branch will be executed; otherwise, they will not be executed. For example: return arguments[0].innerText.length >= 5, which checks if the text length of the current loop item is greater than 5. Note that this is used in combination with element-related loop types (e.g., non-fixed element lists)."></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
</div>
</div>
<div style="margin-top:5px">
<label>Wait for the following elements to appear <b>before</b> executing:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" style="min-height: 30px" v-model='list.nl[index.nowNodeIndex]["parameters"]["waitElement"]'
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" style="min-height: 30px" v-model='list.nl[index.nowNodeIndex]["parameters"]["waitElement"]'
placeholder="Enter the XPath of the element to wait for, leave blank to skip waiting"></textarea>
<label style="margin-top:5px">In which iframe is the element located? Set to 0 if the element is not inside an iframe:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="list.nl[index.nowNodeIndex]['parameters']['waitElementIframeIndex']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="list.nl[index.nowNodeIndex]['parameters']['waitElementIframeIndex']" type="number" required></input>
<label style="margin-top:5px">Maximum waiting time for element appearance (in seconds):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="list.nl[index.nowNodeIndex]['parameters']['waitElementTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="list.nl[index.nowNodeIndex]['parameters']['waitElementTime']" type="number" required></input>
<div v-if="nodeType!=10">
<label style="margin-top:5px">Wait seconds <b>after</b> execution (can set decimal values, e.g., 0.5):</label>
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["wait"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["wait"]'></input>
<label>Wait Type</label>
<select v-model='list.nl[index.nowNodeIndex]["parameters"]["waitType"]' class="form-control">
<option :value = 0>Fixed wait (set to wait for 10 seconds then it will wait for 10 seconds)</option>
@ -681,13 +681,13 @@ If the expression returns a value greater than 0 or evaluates to True, the opera
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body" style="height:60vh;overflow: auto">
<input onkeydown="inputDelete(event)" id="serviceId" type="hidden" name="serviceId" value="-1"></input>
<input onkeydown="inputDelete(event)" id="url" type="hidden" name="url" value="about:blank"></input>
<input id="create_time" type="hidden"></input>
<input spellcheck=false onkeydown="inputDelete(event)" id="serviceId" type="hidden" name="serviceId" value="-1"></input>
<input spellcheck=false onkeydown="inputDelete(event)" id="url" type="hidden" name="url" value="about:blank"></input>
<input spellcheck=false id="create_time" type="hidden"></input>
<label>Task Name:</label>
<input onkeydown="inputDelete(event)" required name="serviceName" value="New Web Crawler Task" id="serviceName" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" required name="serviceName" value="New Web Crawler Task" id="serviceName" class="form-control"></input>
<label>Task Description:</label>
<input onkeydown="inputDelete(event)" id="serviceDescription" name="serviceDescription" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" id="serviceDescription" name="serviceDescription" class="form-control"></input>
<label>Export Data Format (Excel/CSV/TXT/Database):</label>
<select id="outputFormat" class="form-control">
<option value = "xlsx">XLSX (EXCEL, note that a single Excel cell can save up to 32767 characters)</option>
@ -697,7 +697,7 @@ If the expression returns a value greater than 0 or evaluates to True, the opera
<option value = "mysql">MySQL Database</option>
</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>
<input onkeydown="inputDelete(event)" value="current_time" id="saveName" class="form-control"></input>
<input spellcheck=false 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>
@ -709,7 +709,7 @@ If the expression returns a value greater than 0 or evaluates to True, the opera
<!-- <option value=1>Yes (Only support on Windows x64 platform)</option>-->
<!-- </select>-->
<label>To modify the input parameters of each operation during execution, read the following Excel (.xlsx) file. Please click the "Read Input Parameters from Excel File" button when calling the task to view the file format:</label>
<input onkeydown="inputDelete(event)" id="inputExcel" name="inputExcel" class="form-control" placeholder="If left empty, input parameters will not be read from Excel. The file path is relative to the EasySpider folder, e.g., inputs/task1.xlsx"></input>
<input spellcheck=false onkeydown="inputDelete(event)" id="inputExcel" name="inputExcel" class="form-control" placeholder="If left empty, input parameters will not be read from Excel. The file path is relative to the EasySpider folder, e.g., inputs/task1.xlsx"></input>
<label>Browser Emulation Type:</label>
<select id="environment" name="environment" class="form-control">
<option value=0>Desktop</option>
@ -721,23 +721,23 @@ If the expression returns a value greater than 0 or evaluates to True, the opera
<option value = 1>Yes</option>
</select>
<label>Save Data Every N Rows (Specify N below, the larger the value, the faster the scraping speed, but there is a risk of data loss if unexpectedly exited):</label>
<input onkeydown="inputDelete(event)" type="number" value="10" id="saveThreshold" name="saveThreshold" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" type="number" value="10" id="saveThreshold" name="saveThreshold" class="form-control"></input>
<label>Do you want to resume execution from the last saved position when unexpectedly exiting and restarting the task (The record interval of the number of collected items is the value set above)?</label>
<select id="startFromExit" name="startFromExit" class="form-control">
<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>
</select>
<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 spellcheck=false 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>
<input onkeydown="inputDelete(event)" type="number" value="15" id="maxViewLength" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" type="number" value="15" id="maxViewLength" class="form-control"></input>
<label>Record log when executing the task:</label>
<select id="recordLog" name="recordLog" class="form-control">
<option value = 1>Yes</option>
<option value = 0>No</option>
</select>
<label>Pause/Continue Task Shortcut Key:</label>
<input onkeydown="inputDelete(event)" type="text" value="p" id="pauseKey" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" type="text" value="p" id="pauseKey" class="form-control"></input>
</div>
<div class="modal-footer">

+ 98
- 98
ElectronJS/src/taskGrid/FlowChart_CN.html Voir le fichier

@ -67,7 +67,7 @@
</div>
<div style="margin-top:20px;border: solid navy;height:850px;overflow: auto;margin-left:10px;margin-right:10px;width:30%;float:right;min-width:300px">
<!-- <div style="display: inline-block;border-bottom:solid 2px;width:100%">
<input style="float:left;margin-left:10px;margin-top:10px;margin-bottom:10px" type="button" class="btn-primary" value="保存任务"></input>
<input spellcheck=false style="float:left;margin-left:10px;margin-top:10px;margin-bottom:10px" type="button" class="btn-primary" value="保存任务"></input>
</div> -->
<div class="Modify" id="app">
<div class="modal fade" id="myModal_XPath" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
@ -80,7 +80,7 @@
<div class="modal-body">
<label>以下提供除默认生成的XPath外其余等价的XPath,都能定位到同一个元素(但不完全准确,可能可以定位到除该元素外的其他元素,因此只是提供在这里作为参考)。 </label>
<label>每行一个XPath(可使用预装的XPath Helper扩展调试):</label>
<textarea id="otherXPaths" onkeydown="inputDelete(event)" class="form-control" rows="4">{{XPaths}}</textarea>
<textarea spellcheck=false id="otherXPaths" onkeydown="inputDelete(event)" class="form-control" rows="4">{{XPaths}}</textarea>
<div>
<img src="../img/XPather_helper.png" style="width:50%;height:50%; margin: 10px auto"></div>
</div>
@ -93,24 +93,24 @@
<div>
<label>提示:鼠标移到笑脸可查看提示,在流程图中<b>双击</b>操作可试运行,<b>右键</b>点击操作查看更多选项。</label>
<label>选项名称</span></label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='list.nl[index.nowNodeIndex]["title"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='list.nl[index.nowNodeIndex]["title"]'></input>
</div>
<!-- 下面是10种不同类型操作选项的不同的配置页面 -->
<div class="elements" v-if="nodeType==1">
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的链接</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的链接</p>
</div>
<div v-if='!useLoop'>
<!-- <label>url:</label>-->
<!-- <input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["url"]'></input>-->
<!-- <input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["url"]'></input>-->
<label v-if='nowNode["parameters"]["url"]!="about:blank"'>链接池(每行一个链接,有多少行链接整个任务流程就会被执行多少次):</label>
<label v-else>链接(只能填写一个链接,因为是手动添加的打开网页操作):</label>
<textarea v-if='nowNode["parameters"]["url"]!="about:blank"' onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["links"]'></textarea>
<input v-else onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["links"]'></input>
<textarea spellcheck=false v-if='nowNode["parameters"]["url"]!="about:blank"' onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["links"]'></textarea>
<input spellcheck=false v-else onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["links"]'></input>
</div>
<label>页面加载最长等待时间(秒):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['maxWaitTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['maxWaitTime']" type="number" required></input>
<label>打开网页后是否向下滚动:</label>
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
<option :value = 0>不滚动</option>
@ -119,9 +119,9 @@
<option :value = 3>一直滚动直到页面内容无变化(需设置好滚动后的等待时间用于检测页面变化)</option>
</select>
<label>滚动次数(滚动类型设置为<b>不滚动</b><b>一直滚动</b>时请忽略此项):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>滚动后等待时间(秒):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<p style="margin-top: 10px">
<a class="btn btn-primary" data-toggle="collapse" href="#collapseOpenPage" role="button" aria-expanded="false" aria-controls="collapseExample">
点此展开/折叠自定义操作
@ -133,25 +133,25 @@
<p style="margin-bottom: 20px;color:white"><a class="btn btn-primary" @click="getCookies">
点击获取当前页面Cookie
</a></p>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='key=value形式,每行一个键值对' v-model='nowNode["parameters"]["cookies"]' id="pageCookies" style="font-size: 14px!important;"></textarea>
</div>
</div>
</div>
<div class="elements" v-if="nodeType==2">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用相对循环内的XPath定位到的元素</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用相对循环内的XPath定位到的元素</p>
</div>
<div>
<label>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></label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode['parameters']['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">点此查看其他等价的XPath</button></p>
</div>
<label>点击后页面加载最长等待时间(秒):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['maxWaitTime']" type="number" required></input>
<input spellcheck=false 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>
@ -170,9 +170,9 @@
<option :value = 3>一直滚动直到页面内容无变化(需设置好滚动后的等待时间用于检测页面变化)</option>
</select>
<label>滚动次数(滚动类型设置为<b>不滚动</b><b>一直滚动</b>时请忽略此项):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>滚动后等待时间(秒):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<label>点击元素后如有弹窗出现,弹窗处理方式:</label>
<p><select v-model='nowNode["parameters"]["alertHandleType"]' class="form-control">
<option :value = 0>无弹窗</option>
@ -187,14 +187,14 @@
<div :class="{collapse: true, 'show': nowNode['parameters']['beforeJS'].length!=0 || nowNode['parameters']['afterJS'].length!=0}" id="collapseExample">
<div>
<label>点击该元素<strong></strong>针对该元素执行一段JavaScript脚本: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].innerText = arguments[0].innerText.replace("上海","Shanghai")即实现了将元素文字中的“上海”替换成”Shanghai“的功能,然后后续如提取数据时就会提取到替换后的值。' v-model='nowNode["parameters"]["beforeJS"]'></textarea>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<label>点击该元素<strong></strong>针对该元素执行一段JavaScript脚本: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].click()即点击此元素' v-model='nowNode["parameters"]["afterJS"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].click()即点击此元素' v-model='nowNode["parameters"]["afterJS"]'></textarea>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["afterJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["afterJSWaitTime"]'></input>
</div>
</div>
@ -206,8 +206,8 @@
<p>
<button class="btn btn-primary" v-on:mousedown= 'addPara'>新增字段</button>
</p>
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["clear"]'></input>提取数据前清空其他操作字段已记录的值</p>
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["newLine"]'></input>此提取数据操作后生成新数据行 <span style="font-size: 30px!important;" title="取消勾选则适用于不想每次提取操作都生成一个新行的场景"></span></p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["clear"]'></input>提取数据前清空其他操作字段已记录的值</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["newLine"]'></input>此提取数据操作后生成新数据行 <span style="font-size: 30px!important;" title="取消勾选则适用于不想每次提取操作都生成一个新行的场景"></span></p>
<div class="toolkitcontain">
<table class="toolkittb2" cellspacing="0">
<tbody>
@ -219,7 +219,7 @@
<table class="toolkittb4" cellspacing="0">
<tbody>
<tr v-for="i in paras.parameters.length">
<td style="padding-left:0px"><input onkeydown="inputDelete(event)" style='padding-left:2px;font-size:13px!important;height:100%' v-model='paras.parameters[i-1]["name"]'></input>
<td style="padding-left:0px"><input spellcheck=false onkeydown="inputDelete(event)" style='padding-left:2px;font-size:13px!important;height:100%' v-model='paras.parameters[i-1]["name"]'></input>
</td>
<td style="width:200px">{{paras.parameters[i-1]["exampleValues"][0]["value"]}}</td>
<td>
@ -234,10 +234,10 @@
<div style="font-size: 13px;" v-if="paraIndex<paras.parameters.length">
<p>当前编辑字段参数名(点击字段的“修改”选项切换参数): </p>
<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 v-if='!paras.parameters[paraIndex]["relative"]'><input onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["iframe"]'></input>元素在iframe内</p>
<p v-if="nowNode['isInLoop']"><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["relative"]'></input>使用相对循环内的XPATH</p>
<p v-if='!paras.parameters[paraIndex]["relative"]'><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='paras.parameters[paraIndex]["iframe"]'></input>元素在iframe内</p>
<p>XPath(所有XPath内均可用Field["字段名"]表示参数值,用eval("你的代码")来替换成自定义的变量): <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"]' placeholder="如果要写相对循环内的xpath,可以写如*../div[1]即匹配当前循环元素的父元素的第一个div子元素"></textarea>
<textarea spellcheck=false 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">
@ -248,14 +248,14 @@
<div>
<div><a href="#" v-on:mousedown="trailPara(paraIndex)" style="text-decoration: none">试运行</a></div>
<label>提取该元素数据<strong></strong>针对该元素执行一段JavaScript脚本: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].innerText = arguments[0].innerText.replace("上海","Shanghai")即实现了将元素文字中的“上海”替换成”Shanghai“的功能,然后后续如提取数据时就会提取到替换后的值。' v-model='paras.parameters[paraIndex]["beforeJS"]'></textarea>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["beforeJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["beforeJSWaitTime"]'></input>
<label>提取该元素数据<strong></strong>针对该元素执行一段JavaScript脚本: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].click()即点击此元素' v-model='paras.parameters[paraIndex]["afterJS"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].click()即点击此元素' v-model='paras.parameters[paraIndex]["afterJS"]'></textarea>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["afterJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["afterJSWaitTime"]'></input>
</div>
</div>
<label>参数类型转换为(用于Excel和数据库):</label>
@ -272,7 +272,7 @@
<option value = "bigInt">大整数(位数超过9位)</option>
</select>
<label>元素找不到时的值:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["default"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["default"]'></input>
<label>采集内容类型</label>
<select v-model='paras.parameters[paraIndex]["contentType"]' class="form-control">
<option :value = 0>文本(包括子元素)</option>
@ -293,14 +293,14 @@
</select>
<div v-if='paras.parameters[paraIndex]["contentType"] == 14'>
<label>属性名称:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["JS"]' placeholder="属性名称,如class表示当前元素的class属性值,即元素所拥有的类名。"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='paras.parameters[paraIndex]["JS"]' placeholder="属性名称,如class表示当前元素的class属性值,即元素所拥有的类名。"></input>
</div>
<div v-else-if='paras.parameters[paraIndex]["contentType"] == 9 || paras.parameters[paraIndex]["contentType"] >= 12'>
<label>JavaScript(也可以不针对该元素,直接写return JS代码即可)/系统命令/Python代码:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='如要针对该元素,则该元素用arguments[0]来表示,示例:return arguments[0].innerText + "美元",即实现了提取该元素innerText并后面加“美元”的功能;不然直接如写return new Date().toString()即可获得当前时间戳。' v-model='paras.parameters[paraIndex]["JS"]'></textarea>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["JSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["JSWaitTime"]'></input>
</div>
<label>节点类型</label>
<select v-model='paras.parameters[paraIndex]["nodeType"]' class="form-control">
@ -328,30 +328,30 @@
<option :value = 0></option>
</select>
<label>参数描述:</label>
<input onkeydown="inputDelete(event)" class="form-control" style="min-height: 60px" v-model='paras.parameters[paraIndex]["desc"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" style="min-height: 60px" v-model='paras.parameters[paraIndex]["desc"]'></input>
</div>
</div>
<div class="elements" v-if="nodeType==4">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的文本(不勾选则每次输入的文本为下方“输入值”文本框内的文本,勾选后会使用所在“文本列表”循环内设置的文本)</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的文本(不勾选则每次输入的文本为下方“输入值”文本框内的文本,勾选后会使用所在“文本列表”循环内设置的文本)</p>
<p v-if="useLoop">
<label>索引值(0表示使用整个当前循环的文本,如果大于0则表示当前文本用~来分割开的文本索引取值,即如果当前循环的文本值为A~B,则索引值为1表示输入A,2表示输入B,0表示输入A~B)</label>
<input onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input></p>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input></p>
</p>
</div>
<div v-if='!useLoop'>
<label>输入值(用Field["字段名"]来输入某字段/自定义操作的最新提取/返回值,用&lt;enter&gt;&lt;ENTER&gt;表示模拟按下回车键):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["value"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["value"]'></input>
</div>
<label>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></label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode.parameters['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="#inputAdvanced" role="button" aria-expanded="false" aria-controls="collapseExample">
@ -361,20 +361,20 @@
<div :class="{collapse: true, 'show': nowNode['parameters']['beforeJS'].length!=0 || nowNode['parameters']['afterJS'].length!=0}" id="inputAdvanced">
<div>
<label>对该元素输入文字<strong></strong>针对该元素执行一段JavaScript脚本: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].innerText = arguments[0].innerText.replace("上海","Shanghai")即实现了将元素文字中的“上海”替换成”Shanghai“的功能,然后后续如提取数据时就会提取到替换后的值。' v-model='nowNode["parameters"]["beforeJS"]'></textarea>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<label>对该元素输入文字<strong></strong>针对该元素执行一段JavaScript脚本: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].click()即点击此元素' v-model='nowNode["parameters"]["afterJS"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder='该元素用arguments[0]来表示,示例JS代码:arguments[0].click()即点击此元素' v-model='nowNode["parameters"]["afterJS"]'></textarea>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["afterJSWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["afterJSWaitTime"]'></input>
</div>
</div>
</div>
<div class="elements" v-if="nodeType==5">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>操作在iframe内</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>操作在iframe内</p>
<label>执行模式</label>
<select v-model='codeMode' class="form-control" @change="handleCodeModeChange">
<option :value = 0>执行一段JavaScript脚本(如要获得返回值则需以return 开头)</option>
@ -390,9 +390,9 @@
</select>
<div v-if='nowNode["parameters"]["codeMode"] < 3 || nowNode["parameters"]["codeMode"] >= 5 && nowNode["parameters"]["codeMode"] <=6'>
<label>代码/脚本内容(用Field["字段名"]来输入某字段/自定义操作的最新提取/返回值): </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["code"]' placeholder="输入JS或系统命令,如:document.body.innerText = '1' 或 python D:/test.py,分别为JS命令和系统命令示例。如选择针对当前循环项的JS脚本,则循环项元素用arguments[0]表示,如arguments[0].style.color = 'blue'"></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["code"]' placeholder="输入JS或系统命令,如:document.body.innerText = '1' 或 python D:/test.py,分别为JS命令和系统命令示例。如选择针对当前循环项的JS脚本,则循环项元素用arguments[0]表示,如arguments[0].style.color = 'blue'"></textarea>
<pre class="form-control" style="background: white; margin-top: 20px; min-height: 200px; font-size: 15px!important; word-wrap: break-word; white-space: pre-wrap; border-radius: 0; border: 1px solid" disabled v-if='nowNode["parameters"]["codeMode"] == 5'>请先阅读此说明,再在上方输入框(不是本框)写具体代码,如果要执行大量代码,可以直接写outside:myCode.py,这样程序就会读取并执行EasySpider目录下的myCode.py中的代码。
注意包含exec和eval操作的语句和XPath不能在当前页面试运行,只能在任务真正调用时运行。
注意包含exec和eval操作的语句和XPath不能在当前页面试运行,只能在任务真正调用时运行。
此选项为高级功能,可以直接用Python代码操纵正在运行中的浏览器,及可以自定义整个执行环境中的变量,并对变量进行修改赋值等操作,示例:
1. 用self.browser表示当前操作的浏览器,可直接用selenium的API进行操作,如self.browser.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END)即可滚动到页面最下方。
2. 自定义一个全局变量:self.myVar = 1
@ -452,7 +452,7 @@ print(emotlib.emoji()) # 使用其中的函数。
</select>
</p>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
</div>
<div v-if='nowNode["parameters"]["codeMode"] == 7'>
<label>此操作可以暂停程序执行,如检测到验证码框出现时暂停执行,直到手动长按键盘自定义暂停/继续快捷键(默认:p键)后才继续执行。</label>
@ -463,35 +463,35 @@ print(emotlib.emoji()) # 使用其中的函数。
<div v-if='nowNode["parameters"]["codeMode"] == 9'>
<label>此操作可以发送邮件,如用于爬虫任务完成后发送邮件通知。</label>
<label>STMP邮件服务器主机:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["host"]' placeholder="如smtp.163.com"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["host"]' placeholder="如smtp.163.com"></input>
<label>邮件服务器端口:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["port"]' placeholder="如465"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["port"]' placeholder="如465"></input>
<label>发件人邮箱用户名:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["username"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["username"]'></input>
<label>发件人邮箱密码(设置了密码注意不要轻易泄露任务文件!):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["password"]' placeholder="多数邮箱服务器为授权码而不是原密码"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["password"]' placeholder="多数邮箱服务器为授权码而不是原密码"></input>
<label>收件人邮箱地址:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["to"]' placeholder="多个收件人用英文逗号隔开"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["to"]' placeholder="多个收件人用英文逗号隔开"></input>
<label>邮件主题:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["subject"]' placeholder="这里写邮件主题"></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["subject"]' placeholder="这里写邮件主题"></input>
<label>邮件内容:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["emailConfig"]["content"]' placeholder="这里写邮件内容"></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["emailConfig"]["content"]' placeholder="这里写邮件内容"></textarea>
</div>
</div>
<div class="elements" v-if="nodeType==6">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的索引值(不勾选则输入为下方“设定值”文本框内的内容,勾选后会使用所在“文本列表”循环内设置的下拉框索引值)</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的索引值(不勾选则输入为下方“设定值”文本框内的内容,勾选后会使用所在“文本列表”循环内设置的下拉框索引值)</p>
<p v-if="useLoop">
<label>相对循环内文本索引值(0表示使用整个当前循环的文本当做索引值,如果大于0则表示当前循环的文本用~来分割开的文本索引取值,即如果当前循环的文本值为2~3,这里填写2,则表示取文本第二项,即取值3,表示设置下拉框为第3项)</label>
<input onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input></p>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input></p>
</p>
</div>
<label>XPath: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode['parameters']['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">点此查看其他等价的XPath</button></p>
<div v-if="!useLoop">
<p>切换模式</p>
@ -502,19 +502,19 @@ print(emotlib.emoji()) # 使用其中的函数。
<option :value=3>按选项文本切换选项</option>
</select>
<p>设定值(不适用于切换到下一个选项模式)</p>
<input class="form-control" id="selectValue" v-model='nowNode["parameters"]["optionValue"]' autoFocus="autofocus" type="text"></input>
<input spellcheck=false class="form-control" id="selectValue" v-model='nowNode["parameters"]["optionValue"]' autoFocus="autofocus" type="text"></input>
</div>
</div>
<div class="elements" v-if="nodeType==7">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内才显示此行元素 -->
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用相对循环内的XPath定位的元素</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用相对循环内的XPath定位的元素</p>
</div>
<div>
<label>XPath: </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode['parameters']['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">点此查看其他等价的XPath</button></p>
</div>
@ -522,7 +522,7 @@ print(emotlib.emoji()) # 使用其中的函数。
</div>
<div class="elements" v-if="nodeType==8">
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>在iframe内操作</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>在iframe内操作</p>
<!-- 循环选项 -->
<label>循环类型:</label>
<select v-model='loopType' class="form-control" @change="handleLoopTypeChange">
@ -537,20 +537,20 @@ print(emotlib.emoji()) # 使用其中的函数。
</select>
<div v-if='parseInt(loopType) < 2'>
<label>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></label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder="循环里的XPath不能用@href或者text()这种写法,只能定位元素不能取属性值,即@href和text()这种写法只在提取数据操作中支持,并且不推荐,建议直接在提取数据操作中选择节点类型和采集内容类型。" v-model='nowNode["parameters"]["xpath"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" placeholder="循环里的XPath不能用@href或者text()这种写法,只能定位元素不能取属性值,即@href和text()这种写法只在提取数据操作中支持,并且不推荐,建议直接在提取数据操作中选择节点类型和采集内容类型。" v-model='nowNode["parameters"]["xpath"]'></textarea>
<p><button type="button" data-toggle="modal" data-target="#myModal_XPath" @click="changeXPaths(nowNode.parameters['allXPaths'])" class="btn btn-primary" style="margin-top: 10px">(测试功能)点此查看其他可能的XPath写法</button></p>
</div>
<div v-else-if='parseInt(loopType) == 2'>
<label>XPath列表:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" placeholder="每行一个XPath,循环里的XPath不能用@href或者text()这种写法,只能定位元素不能取属性值,即@href和text()这种写法只在提取数据操作中支持,并且不推荐,建议直接在提取数据操作中选择节点类型和采集内容类型。" v-model='nowNode["parameters"]["pathList"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" placeholder="每行一个XPath,循环里的XPath不能用@href或者text()这种写法,只能定位元素不能取属性值,即@href和text()这种写法只在提取数据操作中支持,并且不推荐,建议直接在提取数据操作中选择节点类型和采集内容类型。" v-model='nowNode["parameters"]["pathList"]'></textarea>
</div>
<div v-else-if='parseInt(loopType) < 5'>
<label>内容列表(用Field["字段名"]来输入某字段/自定义操作的最新提取/返回值):</label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" placeholder="每行一个文本/网址,用~来分割文字,即如果某行值为A~B,则在输入文字操作中可以设定索引值为1表示输入A,2表示输入B,0表示输入A~B" v-model='nowNode["parameters"]["textList"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" placeholder="每行一个文本/网址,用~来分割文字,即如果某行值为A~B,则在输入文字操作中可以设定索引值为1表示输入A,2表示输入B,0表示输入A~B" v-model='nowNode["parameters"]["textList"]'></textarea>
</div>
<div v-else-if='parseInt(loopType) < 8'>
<label>代码/脚本内容(用Field["字段名"]来输入某字段/自定义操作的最新提取/返回值): </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="命令返回值大于0或为真则继续循环,否则停止循环。如:return document.body.scrollWidth > 1000 或 python D:/test.py,分别为JS命令和系统命令返回值示例。"></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="命令返回值大于0或为真则继续循环,否则停止循环。如:return document.body.scrollWidth > 1000 或 python D:/test.py,分别为JS命令和系统命令返回值示例。"></textarea>
<pre class="form-control" style="background: white; margin-top: 20px; min-height: 220px; font-size: 15px!important; word-wrap: break-word; white-space: pre-wrap; border-radius: 0; border: 1px solid" disabled v-if='parseInt(loopType) == 7'>请先阅读此说明,再在上方输入框(不是本框)写具体代码,如果要执行大量代码,可以直接写outside:myCode.py,这样程序就会读取并执行EasySpider目录下的myCode.py中的代码。
根据Python代码的表达式值来决定是否循环,示例:
1. 返回当前浏览器对象的相关值,用self.browser表示当前操作的浏览器,可直接用selenium的API进行操作,如self.browser.find_element(By.CSS_SELECTOR, "body").text=="123",表示判断当前页面是否为123这个文本。
@ -560,14 +560,14 @@ print(emotlib.emoji()) # 使用其中的函数。
以上表达式返回值大于0或为真则继续循环,否则停止循环。
</pre>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
</div>
<!-- 这里添加退出循环条件,找不到元素肯定退出循环 -->
<div v-if='parseInt(loopType) == 0'>
<label>最多执行循环次数(0代表无限循环直到找不到元素或检测不到页面元素内容变化为止):</label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["exitCount"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["exitCount"]'></input>
<label>检测页面以下元素内容不变化时退出循环(次数为0时生效,如果是多层嵌套iframe,建议写一个只有要提取的iframe页面内才有的元素的XPath,如/html/body/div[@class='LeftSide_menu']):</label>
<input onkeydown="inputDelete(event)" required class="form-control" type="text" v-model='nowNode["parameters"]["exitElement"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="text" v-model='nowNode["parameters"]["exitElement"]'></input>
</div>
<div id="breakAdvanced" v-if='nowNode["parameters"]["loopType"] < 5'>
@ -579,15 +579,15 @@ print(emotlib.emoji()) # 使用其中的函数。
<option :value = 2>操作系统级别命令</option>
</select>
<div>
<textarea style="margin-top: 10px" onkeydown="inputDelete(event)" class="form-control" rows="2"
<textarea spellcheck=false style="margin-top: 10px" onkeydown="inputDelete(event)" class="form-control" rows="2"
placeholder='命令返回值小于等于0或为假时则直接退出循环,不管其他条件如何。如:document.evaluate("//div[1]/a", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue == null 或 python D:/test.py,分别为JS命令(判断某元素是否存在)和系统命令返回值示例。' v-model='nowNode["parameters"]["breakCode"]'></textarea>
<label>最长等待脚本执行时间(0代表无限等待):</label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["breakCodeWaitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["breakCodeWaitTime"]'></input>
</div>
</div>
</div>
<label><b>历史记录回退后</b>等待秒数:</label>
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["historyWait"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["historyWait"]'></input>
<label>执行完是否向下滚动:</label>
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
<option :value = 0>不滚动</option>
@ -596,9 +596,9 @@ print(emotlib.emoji()) # 使用其中的函数。
<option :value = 3>一直滚动直到页面内容无变化(需设置好滚动后的等待时间用于检测页面变化)</option>
</select>
<label>滚动次数(滚动类型设置为<b>不滚动</b><b>一直滚动</b>时请忽略此项):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>滚动后等待时间(秒):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollWaitTime']" type="number" required></input>
</div>
<div class="elements" v-if="nodeType==9">
@ -607,7 +607,7 @@ print(emotlib.emoji()) # 使用其中的函数。
<div class="elements" v-if="nodeType==10">
<label>判断条件是从左往右判断的,即如果最左边的条件分支的判断条件满足,则执行最左边分支内的操作,否则判断从左向右第二个分支的条件是否满足,以此类推。设计任务时点击分支即可在浏览器中<b>动态调试</b>分支是否满足(不适用于系统命令和Python Eval操作)。</label>
<p><input onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>在iframe内操作</p>
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>在iframe内操作</p>
<label>条件类型:</label>
<select v-model='TClass' class="form-control" @change="handleJudgeTypeChange">
<option :value = 0>无条件</option>
@ -623,11 +623,11 @@ print(emotlib.emoji()) # 使用其中的函数。
<div v-if='TClass > 0 && TClass < 5'>
<label>包含的文字/元素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></label>
<textarea onkeydown="inputDelete(event)" required placeholder="如果是当前循环包含元素,则输入相对元素的xpath(如/div[2]/div[1]/img,如果写相对路径,需要写成/*//img,即检测当前循环项所有的子孙元素是否存在img标签)。" class="form-control" rows="3" v-model='nowNode["parameters"]["value"]'></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" required placeholder="如果是当前循环包含元素,则输入相对元素的xpath(如/div[2]/div[1]/img,如果写相对路径,需要写成/*//img,即检测当前循环项所有的子孙元素是否存在img标签)。" class="form-control" rows="3" v-model='nowNode["parameters"]["value"]'></textarea>
</div>
<div v-else-if='TClass > 0 && TClass < 7 || TClass == 8'>
<label>代码/脚本内容(用Field["字段名"]来输入某字段/自定义操作的最新提取/返回值): </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="命令返回值大于0或为真则执行此分支内操作,否则不执行。如:return document.body.scrollWidth > 1000 或 python D:/test.py,分别为JS命令和系统命令返回值示例。"></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="命令返回值大于0或为真则执行此分支内操作,否则不执行。如:return document.body.scrollWidth > 1000 或 python D:/test.py,分别为JS命令和系统命令返回值示例。"></textarea>
<pre class="form-control" style="background: white; margin-top: 20px; min-height: 200px; font-size: 15px!important; word-wrap: break-word!important; white-space: pre-wrap; border-radius: 0; border: 1px solid" disabled v-if='TClass == 8'>请先阅读此说明,再在上方输入框(不是本框)写具体代码,如果要执行大量代码,可以直接写outside:myCode.py,这样程序就会读取并执行EasySpider目录下的myCode.py中的代码。
根据Python代码的表达式值来判断条件是否满足,示例:
1. 返回当前浏览器对象的相关值,用self.browser表示当前操作的浏览器,可直接用selenium的API进行操作,如self.browser.find_element(By.CSS_SELECTOR, "body").text=="123",表示判断当前页面是否为123这个文本。
@ -637,26 +637,26 @@ print(emotlib.emoji()) # 使用其中的函数。
以上表达式返回值大于0或为则执行此分支内操作,否则不执行。
</pre>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
</div>
<div v-else-if='TClass == 7'>
<label>代码/脚本内容(<a href="https://github.com/NaiboWang/EasySpider/wiki/Example-of-JavaScript-instruction-for-the-current-iteration-in-a-conditional-statement" target="_blank">点击此处</a>查看更多示例): </label>
<textarea onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="输入针对该循环项的JS命令,该循环项用arguments[0]表示,返回值大于0或为真则执行此分支内操作,否则不执行。如:return arguments[0].innerText.length >=5 即判断当前循环项的文本长度是否大于5,注意要配合循环类型为元素相关(如不固定元素列表)使用。"></textarea>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" v-model='nowNode["parameters"]["code"]' placeholder="输入针对该循环项的JS命令,该循环项用arguments[0]表示,返回值大于0或为真则执行此分支内操作,否则不执行。如:return arguments[0].innerText.length >=5 即判断当前循环项的文本长度是否大于5,注意要配合循环类型为元素相关(如不固定元素列表)使用。"></textarea>
<label>最长等待脚本执行时间(0代表无限等待): </label>
<input onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["waitTime"]'></input>
</div>
</div>
<div style="margin-top:5px">
<label>操作<b>执行前</b>等待以下元素出现:</label>
<textarea onkeydown="inputDelete(event)" class="form-control" style="min-height: 30px" v-model='list.nl[index.nowNodeIndex]["parameters"]["waitElement"]'
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" style="min-height: 30px" v-model='list.nl[index.nowNodeIndex]["parameters"]["waitElement"]'
placeholder="填写要等待出现元素的XPath,不填写则不等待"></textarea>
<label style="margin-top:5px">要等待的元素在页面第几个iframe中,0表示元素不在iframe中:</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="list.nl[index.nowNodeIndex]['parameters']['waitElementIframeIndex']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="list.nl[index.nowNodeIndex]['parameters']['waitElementIframeIndex']" type="number" required></input>
<label style="margin-top:5px">元素出现的最长等待时间(秒):</label>
<input onkeydown="inputDelete(event)" class="form-control" v-model.number="list.nl[index.nowNodeIndex]['parameters']['waitElementTime']" type="number" required></input>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="list.nl[index.nowNodeIndex]['parameters']['waitElementTime']" type="number" required></input>
<div v-if="nodeType!=10">
<label style="margin-top:5px">操作<b>执行后</b>等待秒数(所有等待时间均可设置为小数,如0.5):</label>
<input onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["wait"]'></input>
<input spellcheck=false onkeydown="inputDelete(event)" required type="number" class="form-control" v-model.number='list.nl[index.nowNodeIndex]["parameters"]["wait"]'></input>
<label style="margin-top:5px">等待类型</label>
<select v-model='list.nl[index.nowNodeIndex]["parameters"]["waitType"]' class="form-control">
<option :value = 0>固定等待(设置等10秒就等10秒)</option>
@ -681,13 +681,13 @@ print(emotlib.emoji()) # 使用其中的函数。
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body" style="height:60vh;overflow: auto">
<input onkeydown="inputDelete(event)" id="serviceId" type="hidden" name="serviceId" value="-1"></input>
<input onkeydown="inputDelete(event)" id="url" type="hidden" name="url" value="about:blank"></input>
<input id="create_time" type="hidden"></input>
<input spellcheck=false onkeydown="inputDelete(event)" id="serviceId" type="hidden" name="serviceId" value="-1"></input>
<input spellcheck=false onkeydown="inputDelete(event)" id="url" type="hidden" name="url" value="about:blank"></input>
<input spellcheck=false id="create_time" type="hidden"></input>
<label>任务名称:</label>
<input onkeydown="inputDelete(event)" required name="serviceName" value="新web采集任务" id="serviceName" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" required name="serviceName" value="新web采集任务" id="serviceName" class="form-control"></input>
<label>任务描述:</label>
<input onkeydown="inputDelete(event)" id="serviceDescription" name="serviceDescription" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" id="serviceDescription" name="serviceDescription" class="form-control"></input>
<label>导出数据格式(Excel/CSV/TXT/数据库,<a href="https://www.bilibili.com/video/BV1os4y1679S/" target="_blank">查看MySQL操作教程</a>):</label>
<select id="outputFormat" class="form-control">
<option value = "xlsx">XLSX(即EXCEL文件,注意Excel单个单元格最多可存储32767字符)</option>
@ -697,7 +697,7 @@ print(emotlib.emoji()) # 使用其中的函数。
<option value = "mysql">MySQL数据库</option>
</select>
<label>导出文件名/数据库表格名称(可使用../表示相对路径以改变文件保存位置,名称中的“current_time”会被替换为执行任务时的时间戳):</label>
<input onkeydown="inputDelete(event)" value="current_time" id="saveName" class="form-control"></input>
<input spellcheck=false 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>
@ -709,7 +709,7 @@ print(emotlib.emoji()) # 使用其中的函数。
<!-- <option value = 1>是(只支持Windows x64系统)</option>-->
<!-- </select>-->
<label>执行时通过读取以下Excel(.xlsx)文件来修改各个操作的输入参数,文件格式请在调用任务时点击“从Excel文件读取输入参数”按钮查看:</label>
<input onkeydown="inputDelete(event)" id="inputExcel" name="inputExcel" class="form-control" placeholder="为空则不从Excel读取输入参数,文件路径相对于EasySpider文件夹,如inputs/task1.xlsx"></input>
<input spellcheck=false onkeydown="inputDelete(event)" id="inputExcel" name="inputExcel" class="form-control" placeholder="为空则不从Excel读取输入参数,文件路径相对于EasySpider文件夹,如inputs/task1.xlsx"></input>
<label>浏览器模拟类型:</label>
<select id="environment" name="environment" class="form-control">
<option value = 0>电脑端</option>
@ -721,23 +721,23 @@ print(emotlib.emoji()) # 使用其中的函数。
<option value = 1></option>
</select>
<label>每采集多少条数据保存一次(值越大采集速度越快,但如果意外退出则有数据丢失风险):</label>
<input onkeydown="inputDelete(event)" type="number" value="10" id="saveThreshold" name="saveThreshold" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" type="number" value="10" id="saveThreshold" name="saveThreshold" class="form-control"></input>
<label>是否要意外退出并重新执行任务时从上次保存的位置继续执行(已采集条数记录间隔为上面设置的值):</label>
<select id="startFromExit" name="startFromExit" class="form-control">
<option value = 0></option>
<option value = 1>是(需要运行同一个任务ID和固定的文件名,请用命令行执行并指定ID)</option>
</select>
<label>任务执行完毕后自动关闭浏览器等待秒数(用户信息临时目录将在浏览器关闭后自动删除):</label>
<input onkeydown="inputDelete(event)" type="number" value="60" id="quitWaitTime" name="quitWaitTime" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" type="number" value="60" id="quitWaitTime" name="quitWaitTime" class="form-control"></input>
<label>控制台预览时数据最大显示长度:</label>
<input onkeydown="inputDelete(event)" type="number" value="15" id="maxViewLength" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" type="number" value="15" id="maxViewLength" class="form-control"></input>
<label>任务执行时是否记录日志:</label>
<select id="recordLog" name="recordLog" class="form-control">
<option value = 1></option>
<option value = 0></option>
</select>
<label>任务暂停/继续快捷键:</label>
<input onkeydown="inputDelete(event)" type="text" value="p" id="pauseKey" class="form-control"></input>
<input spellcheck=false onkeydown="inputDelete(event)" type="text" value="p" id="pauseKey" class="form-control"></input>
</div>
<div class="modal-footer">

+ 8
- 8
ElectronJS/src/taskGrid/logic.js Voir le fichier

@ -290,7 +290,7 @@ function addParameters(t) {
t["parameters"]["optionValue"] = ""; //下拉值
t["parameters"]["index"] = 0; //输入框索引
} else if (t.option == 8) { //循环
t["title"] = LANG("循环 - 单个元素", "Loop - single element");
t["title"] = LANG("循环 - 单个元素", "Loop - Single Element");
t["parameters"]["scrollType"] = 0; //滚动类型,0不滚动,1向下滚动1屏,2滚动到底部
t["parameters"]["scrollCount"] = 1; //滚动次数
t["parameters"]["scrollWaitTime"] = 1; //滚动后等待时间
@ -307,7 +307,7 @@ function addParameters(t) {
t["parameters"]["breakCode"] = ""; //break条件
t["parameters"]["breakCodeWaitTime"] = 0; //break条件等待时间
} else if (t.option == 9) { //条件
t["title"] = LANG("判断条件 - 从左往右依次判断", "Judgment condition - judge from left to right");
t["title"] = LANG("判断条件 - 从左往右依次判断", "Judgment Condition - Judge from Left to Right");
} else if (t.option == 10) { //条件分支
t["parameters"]["class"] = 0; //0代表什么条件都没有,1代表当前页面包括文本,2代表当前页面包括元素,3代表当前循环包括文本,4代表当前循环包括元素
t["parameters"]["value"] = ""; //相关值
@ -366,17 +366,17 @@ function modifyParameters(t, para) {
t["parameters"]["allXPaths"] = para["allXPaths"];
t["parameters"]["textList"] = para["value"];
if (para["nextPage"]) { //循环点击下一页的情况下
t["title"] = LANG("循环点击下一页", "Loop click next page");
t["title"] = LANG("循环点击下一页", "Loop Click Next Page");
} else if (para["type"] == "loopClickSingle") { //循环点击单个元素
t["title"] = LANG("循环点击单个元素", "Loop click single element");
t["title"] = LANG("循环点击单个元素", "Loop Click Single Element");
} else if (para["type"] == "loopClickEvery") { //循环点击每个元素
t["title"] = LANG("循环点击每个元素", "Loop click every element");
t["title"] = LANG("循环点击每个元素", "Loop click Every Element");
} else if (para["type"] == "loopMouseMove") { //循环移动到单个元素
t["title"] = LANG("循环移动到每个元素", "Loop move to every element");
t["title"] = LANG("循环移动到每个元素", "Loop Move to Every Element");
} else if (para["type"] == "multiCollectWithPattern") {
t["title"] = LANG("循环采集数据", "Loop collect data");
t["title"] = LANG("循环采集数据", "Loop Collect Data");
} else if (para["type"] == "batchInputText") {
t["title"] = LANG("循环输入文字", "Loop input text");
t["title"] = LANG("循环输入文字", "Loop Input Text");
} else {
t["title"] = LANG("循环", "Loop");
}

+ 6
- 2
Extension/manifest_v3/src/content-scripts/toolkit.vue Voir le fichier

@ -193,7 +193,7 @@
<span
style="font-size: 15px"> 请在页面上右键选择要点击的下一页按钮/链接如要取消设置翻页操作请点击下方取消选项</span>
<div style="font-size: 15px" v-if="list.nl.length==1">
已选中一个元素您可以点击下方选项确认设置翻页操作
已选中一个元素<span style="color:darkviolet">{{getSelectedInnerText()}}</span>您可以点击下方选项确认设置翻页操作
</div>
<div style="font-size: 15px; color: #c82333;" v-else-if="list.nl.length>1">
翻页操作只能设置一个元素请点击下方取消翻页操作选项并重新选择
@ -415,7 +415,7 @@
<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.
A single element has been selected: <span style="color:darkviolet">{{getSelectedInnerText()}}</span>, 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
@ -773,6 +773,10 @@ export default {
this.selectStatus = true;
clearReady();
},
getSelectedInnerText: function () { //
let l = 10;
return global.nodeList[0]["node"].innerText.trim().length > l ? global.nodeList[0]["node"].innerText.trim().substring(0, l) + "..." : global.nodeList[0]["node"].innerText.trim();
},
getSelectedText: function () { //
generateParameters(11, true, false);
this.selectStatus = true;

Chargement…
Annuler
Enregistrer