2023-12-19 11:44:59 +08:00

801 lines
78 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<script src="jquery-3.4.1.min.js"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="bootstrap/js/bootstrap.js"></script>
<script src="vue.js"></script>
<link rel="stylesheet" href="bootstrap/css/bootstrap.css"></link>
<link rel="stylesheet" href="FlowChart.css"></link>
<title>Workflow Manager</title>
</head>
<body>
<div id="tip" class="alert alert-success alert-dismissible fade show" style="position: fixed; width:100%;display: none;">
<button type="button" class="close" data-dismiss="alert">&times;</button> <span id="tip_message">Tip: Save successful!</span>
</div>
<div id="tipInfo" class="alert alert-info alert-dismissible fade show" style="position: fixed; width:100%;display: none;">
<button type="button" class="close" data-dismiss="alert">&times;</button> <span id="info_message">Tip: The task version you loaded is not the latest, which may cause compatibility issues.</span>
</div>
<div id="tipError" class="alert alert-danger alert-dismissible fade show" style="position: fixed; width:100%;display: none;">
<button type="button" class="close" data-dismiss="alert">&times;</button> <span id="error_message">Tip: The save name does not conform to MySQL table naming conventions, please try again!</span>
</div>
<div id="navigator">
<nav aria-label="breadcrumb" v-if="type==1">
<ol class="breadcrumb" style="padding-left:23px;padding-bottom: 0;margin-bottom:0;background-color: white">
<li @click="gotoHome" class="breadcrumb-item"><a href="#">{{"Home~首页" | lang}}</a></li>
<li @click="gotoInfo" aria-current="page" class="breadcrumb-item" style="color: black"><a href="#">{{"Task Information~任务信息" | lang}}</a></li>
<li aria-current="page" class="breadcrumb-item active" style="color: black">{{"Task Flow~任务流程" | lang}}</li>
</ol>
</nav>
</div>
<div style="display:flex">
<div style="width: 200px;float:left;overflow: auto">
<div class="toolbox" style="text-align:center;margin: 20px;border-radius:10px;border:navy solid;background-color:rgb(242,243,245);z-index: 9999;">
<div style="padding: 10px;border-radius:10px;font-size: 20px;">Toolkit</div>
<button type="button" id="save" data-toggle="modal" data-target="#myModal" onmousedown="$('#myModal').modal('show');" class="btn btn-primary">Save Task</button>
<button type="button" data=1 draggable="true" class="btn btn-outline-primary options">Open Page</button>
<button type="button" data=2 draggable="true" class="btn btn-outline-primary options">Click Element</button>
<button type="button" data=3 draggable="true" class="btn btn-outline-primary options">Collect Data</button>
<button type="button" data=4 draggable="true" class="btn btn-outline-primary options">Input Text</button>
<button type="button" data=5 draggable="true" class="btn btn-outline-primary options" style="font-weight: bold; font-size: 14px!important;">Custom Action</button>
<button type="button" data=6 draggable="true" style="font-size: 14px!important;" class="btn btn-outline-primary options">Change Option</button>
<button type="button" data=7 draggable="true" class="btn btn-outline-primary options">Mouse Move</button>
<button type="button" data=8 draggable="true" class="btn btn-outline-primary options" style="font-weight: bold">Loop</button>
<button type="button" data=9 draggable="true" class="btn btn-outline-primary options" style="font-weight: bold">If Condition</button>
<div>-----------------</div>
<button type="button" data=13 draggable="true" class="btn btn-outline-primary options" title="Adjust the position of the next node/operation to be inserted">Set Anchor</button>
<button type="button" data=10 class="btn btn-outline-primary options">Cut Element</button>
<button type="button" data=11 class="btn btn-outline-primary options">Copy Element</button>
<button type="button" data=12 class="btn btn-outline-primary options">Del Element</button>
<button type="button" data=0 class="btn btn-outline-primary2 options">Cancel</button>
<div style="text-align: left;margin: 10px;font-size:15px!important">Drag button above to the flowchart to insert.</div>
</div>
</div>
<div style="margin-top:20px;border: solid;height:850px;overflow: auto;width:58%;float:right" id="flowchart_graph">
<div id="0" class="clk" data="0">
</div>
<div style="border-radius: 50%;width: 40px;height: 40px;border:solid black;margin: 5px auto;background-color:lightcyan">
<p style="font-size: 22px!important;text-align: center;margin-left: 1px;"></p>
</div>
</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 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">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Equivalent XPath</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<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 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>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal -->
</div>
<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 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 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 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 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 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>
<option :value = 1>Scroll one screen</option>
<option :value = 2>Scroll to the end</option>
<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 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 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
</a>
</p>
<div :class="{collapse: true, 'show': nowNode['parameters']['cookies'].length!=0}" id="collapseOpenPage">
<div>
<label>Set Cookies after page loaded: </label>
<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 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 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 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 (Or use "point(10,10)" to represent clicking on the web page at coordinate position (10, 10), suitable for the situation when need to click on a blank area to leave popup dialog): <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 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 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>
<option :value = 1>JavaScript</option>
</select>
<label>Open link in new tab:</label>
<select v-model='nowNode["parameters"]["newTab"]' class="form-control">
<option :value = 1>Yes</option>
<option :value = 0>No</option>
</select>
<label>Whether to scroll down after clicking:</label>
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
<option :value = 0>No Scrolling</option>
<option :value = 1>Scroll one screen</option>
<option :value = 2>Scroll to the end</option>
<option :value = 3>Keep scrolling until the page data does not change</option>
</select>
<label>Scroll Times:</label>
<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 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>
<option :value = 1>Accept pop-up window</option>
<option :value = 2>Reject pop-up window (only for Confirm pop-up window)</option>
</select></p>
<p style="margin-top: 10px">
<a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
Click here to expand/collapse advanced operations
</a>
</p>
<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 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 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 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 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==3">
<p>
<button class="btn btn-primary" v-on:mousedown= 'addParam'>New Field</button>
</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>
<th>Field Name</th>
<th style="width:200px">Example Value</th>
<th>Operations</th>
</tbody>
</table>
<table class="toolkittb4" cellspacing="0">
<tbody>
<tr v-for="i in params.parameters.length">
<td style="padding-left:0px"><input spellcheck=false onkeydown="inputDelete(event)" style='padding-left:2px;font-size:13px!important;height:100%' v-model='params.parameters[i-1]["name"]'></input>
</td>
<td style="width:200px">{{params.parameters[i-1]["exampleValues"][0]["value"]}}</td>
<td>
<a v-on:mousedown="modifyParam(i-1)">Modify</a>
<a v-on:mousedown="deleteParam(i-1)">Delete</a>
<a v-on:mousedown="upParam(i-1)">Up</a>
<a v-on:mousedown="downParam(i-1)">Down</a>
</td>
</tr>
</table>
</div>
<div style="font-size: 13px;" v-if="paraIndex<params.parameters.length">
<p>Current parameter name (Clicking on the "Modify" option of the field toggles the parameters)</p>
<label><strong>{{params.parameters[paraIndex]["name"]}}</strong></label>
<p v-if="nowNode['isInLoop']"><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='params.parameters[paraIndex]["relative"]'></input>Use relative XPath</p>
<p v-if='!params.parameters[paraIndex]["relative"]'><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='params.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 spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="2" v-model='params.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(params.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">
Click here to expand/collapse advanced operations
</a>
</p>
<div :class="{collapse: true, 'show': params.parameters[paraIndex]['beforeJS'].length!=0 || params.parameters[paraIndex]['afterJS'].length!=0}" id="elementAdvanced">
<div>
<div><a href="#" v-on:mousedown="trailParam(paraIndex)" style="text-decoration: none">Trail Run</a></div>
<label>Execute a JavaScript script <strong>before</strong> extracting data from this element: </label>
<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='params.parameters[paraIndex]["beforeJS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='params.parameters[paraIndex]["beforeJSWaitTime"]'></input>
<label>Execute a JavaScript script <strong>after</strong> extracting data from this element: </label>
<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='params.parameters[paraIndex]["afterJS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='params.parameters[paraIndex]["afterJSWaitTime"]'></input>
</div>
</div>
<label>Parameter type conversion (for Excel and Database):</label>
<select v-model='params.parameters[paraIndex]["paraType"]' class="form-control">
<option value = "text">Text (for single values estimated to exceed 10,000 in length, please choose Large Text)</option>
<option value = "int">Integer (up to 9 digits)</option>
<option value = "double">Floating Number (Decimal)</option>
<option value = "mediumText">Large Text (single value length exceeding 10,000 but less than 1,000,000)</option>
<option value = "datetime">Date Time</option>
<option value = "date">Date</option>
<option value = "time">Time</option>
<option value = "varchar">Small Text (single value length less than 50)</option>
<option value = "longText">Extra Large Text (single value length exceeding 1,000,000)</option>
<option value = "bigInt">Large Integer (more than 9 digits)</option>
</select>
<label>Default value when cannot find this element:</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='params.parameters[paraIndex]["default"]'></textarea>
<label>Extract Type</label>
<select v-model='params.parameters[paraIndex]["contentType"]' class="form-control">
<option :value = 0>Text (include child element)</option>
<option :value = 1>Text (exclude child element)</option>
<option :value = 2>innerHTML</option>
<option :value = 3>outerHTML</option>
<option :value = 4>Background Image Address</option>
<option :value = 5>Webpage URL</option>
<option :value = 6>Webpage Title</option>
<option :value = 7>Element Screenshot</option>
<option :value = 8>OCR Results</option>
<option :value = 14>Properties of elements</option>
<option :value = 9>Return value of JavaScript code (for this element), starting with 'return')</option>
<option :value = 12>System command return value</option>
<option :value = 13>Value of a Python expression (the "eval" operation)</option>
<option :value = 10>Selected value of the current select box</option>
<option :value = 11>Selected text of the current select box</option>
</select>
<div v-if='params.parameters[paraIndex]["contentType"] == 14'>
<label>Attribute Name:</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='params.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='params.parameters[paraIndex]["contentType"] == 9 || params.parameters[paraIndex]["contentType"] >= 12'>
<label>Code (Use Field["FieldName"] to input the lastest value of a field): </label>
<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='params.parameters[paraIndex]["JS"]'></textarea>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<input spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='params.parameters[paraIndex]["JSWaitTime"]'></input>
</div>
<label>Node Type</label>
<select v-model='params.parameters[paraIndex]["nodeType"]' class="form-control">
<option :value = 0>Ordinary Node</option>
<option :value = 1>Link Text</option>
<option :value = 2>Link Address</option>
<option :value = 3>Form Value</option>
<option :value = 4>Image Address</option>
</select>
<div v-if='params.parameters[paraIndex]["nodeType"] == 4'>
<label>Whether to <b>download image</b> after extracting the image address: </label>
<select v-model='params.parameters[paraIndex]["downloadPic"]' class="form-control">
<option :value = 0>No</option>
<option :value = 1>Yes</option>
</select>
</div>
<!-- <label>提取方式</label>-->
<!-- <select v-model='params.parameters[paraIndex]["extractType"]' class="form-control">-->
<!-- <option :value = 0>普通提取</option>-->
<!-- <option :value = 1>OCR提取</option>-->
<!-- </select>-->
<label style="margin-top: 15px">Whether to save this field: (Choose 'No' if you only want to treat this field as a variable and not save it):</label>
<select v-model='params.parameters[paraIndex]["recordASField"]' class="form-control">
<option :value = 1>Yes</option>
<option :value = 0>No</option>
</select>
<label>Parameter Description:</label>
<textarea spellcheck=false onkeydown="inputDelete(event)" class="form-control" style="min-height: 60px" v-model='params.parameters[paraIndex]["desc"]'></textarea>
</div>
</div>
<div class="elements" v-if="nodeType==4">
<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 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 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 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 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">
Click here to expand/collapse advanced operations
</a>
</p>
<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 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 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 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 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 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>
<option :value = 1>Execute operating system-level command</option>
<option v-if="nowNode['isInLoop']" :value = 2>Execute JavaScript script for the current element inside the loop</option>
<option v-if="nowNode['isInLoop']" :value = 3>Exit Current Loop (the "Break" operation)</option>
<option v-if="nowNode['isInLoop']" :value = 4>Skip Current Loop (the "Continue" operation)</option>
<option :value = 5>Run Python code on current environment (the "exec" operation)</option>
<option :value = 6>Get value of a Python expression (the "eval" operation)</option>
<option :value = 7>Pause program execution (such as when the captcha box appears)</option>
<option :value = 8>Refresh page</option>
<option :value = 9>Send Email</option>
</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 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:
1. 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").send_keys(Keys.END)` to scroll to the bottom.
2. Define a global variable: `self.myVar = 1`
3. Manipulate the above-defined global variable: `self.myVar = self.myVar + 1`
4. Print the above-defined global variable: `print(self.myVar)`
5. Assign the value of a custom variable to the value extracted from a field: `self.myVar = self.outputParameters["Field Name"]`
If you want to record your custom variable as a field, please select the next option, "Get value of a Python expression (the "eval" operation)"
6. If you want to import and use a third-party library that the program itself does not carry, you need to first use tools such as pip to install this library locally, and then add the path of the installed library before import, like:
(1) In the system command line execute the following command to install the library:
pip install emotlib
(2) Write the following code in the code box:
sys.path.append("D:/Python38/Lib/site-packages") # Assume emotlib library exists in this path
import emotlib # Now you can use emotlib library
print(emotlib.emoji()) # Use one of its functions.
</pre>
<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"] == 6'>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.
This option is an advanced feature that allows directly returning the expression value of Python code, and in other places, use Field["FieldName"] to represent the return value of this operation.. 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` to return the text on the current page.
2. Return the value of a custom global variable: `self.myVar`
3. Return the result of a conditional statement: `self.myVar == 1`
4. Determining whether the value extracted from a certain field is equal to the value of a certain variable: self.outputParameters["field name"] == self.myVar
Please note that this feature does not support assigning values to variables. In other words, you cannot write something like `self.myVar = 1`. If you want to perform assignment operations, please select the previous option, "Run Python code on current environment (the "exec" operation)"</pre>
<p style="margin-top: 15px">Whether to record the output/return value of the execution as a field: </p>
<p><select v-model='nowNode["parameters"]["recordASField"]' class="form-control">
<option :value = 0>No</option>
<option :value = 1>Yes</option>
</select></p>
<p><label>Convert parameter type to:</label>
<select v-model='nowNode["parameters"]["paraType"]' class="form-control">
<option value = "text">Text (for single values estimated to exceed 10,000 in length, please choose Large Text)</option>
<option value = "int">Integer (up to 9 digits)</option>
<option value = "double">Floating Number (Decimal)</option>
<option value = "mediumText">Large Text (single value length exceeding 10,000 but less than 1,000,000)</option>
<option value = "datetime">Date Time</option>
<option value = "date">Date</option>
<option value = "time">Time</option>
<option value = "varchar">Small Text (single value length less than 50)</option>
<option value = "longText">Extra Large Text (single value length exceeding 1,000,000)</option>
<option value = "bigInt">Large Integer (more than 9 digits)</option>
</select>
</p>
<p>
<label>Clear values of other parameters before record as a field:</label>
<select v-model='nowNode["parameters"]["clear"]' class="form-control">
<option :value = 0>No</option>
<option :value = 1>Yes</option>
</select>
</p>
<p>
<label>This operation will generate a new row of data: </label>
<select v-model='nowNode["parameters"]["newLine"]' class="form-control">
<option :value = 1>Yes</option>
<option :value = 0>No</option>
</select>
</p>
<label>Maximum wait time for script execution (0 represents unlimited wait time): </label>
<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>
</div>
<div v-if='nowNode["parameters"]["codeMode"] == 8'>
<label>This operation can refresh the current page.</label>
</div>
<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 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 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 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 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 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 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 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 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 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 spellcheck=false onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input>
</p>
</div>
<label>XPath: </label>
<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>
<select class="form-control" v-model='nowNode["parameters"]["optionMode"]'>
<option :value = 0>Switch to the next option</option>
<option :value = 1>Switch options by index (0 is the first option)</option>
<option :value = 2>Switch options by option value</option>
<option :value = 3>Switch options by option text</option>
</select>
<p>Set value (not applicable for "Switch to the next option" mode)</p>
<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 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 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 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>
</div>
<div class="elements" v-if="nodeType==8">
<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">
<option :value = 0>Single Element</option>
<option :value = 1>Unfixed Element List</option>
<option :value = 2>Fixed Element List</option>
<option :value = 3>Text List</option>
<option :value = 4>Weblink List</option>
<option :value = 5>Return value of JavaScript command (start with 'return ')</option>
<option :value = 6>Return value of system command</option>
<option :value = 7>Return value of Python code under current environment</option>
</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 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 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 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 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".
2. Return the value of a custom global variable: `self.myVar`
3. Return the result of a conditional statement: `self.myVar == 1`
4. Determining whether the value extracted from a certain field is equal to the value of a certain variable: self.outputParameters["field name"] == self.myVar
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 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 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 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'>
<div>
<p><label>(Advanced Operation) Define loop exit condition using code/script; or you can add a <b>Custom Action</b>, then select the "Exit Loop" option:</label></p>
<select v-model='nowNode["parameters"]["breakMode"]' class="form-control" style="font-weight: bold">
<option :value = 0>Do not set script (even if a script is written below, it will not be executed)</option>
<option :value = 1>JavaScript script (start with 'return ')</option>
<option :value = 2>Operating system-level command</option>
</select>
<div>
<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 spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["breakCodeWaitTime"]'></input>
</div>
</div>
</div>
<div v-if="parseInt(loopType) < 5 && parseInt(loopType) > 0">
<label>Skip the first few loops (enter 2 to skip the first 2 loops):</label>
<input spellcheck="false" onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["skipCount"]'></input>
</div>
<label>Waiting time in seconds after a history record rollback: </label>
<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>
<option :value = 1>Scroll one screen</option>
<option :value = 2>Scroll to the end</option>
<option :value = 3>Keep scrolling until the page data does not change</option>
</select>
<label>Scroll Times:</label>
<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 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">
<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>
</div>
<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 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>
<option :value = 1>Text inside current page</option>
<option :value = 2>Element inside current page</option>
<option v-if="nowNode['isInLoop']" :value = 3>Text inside current loop</option>
<option v-if="nowNode['isInLoop']" :value = 4>Element inside current loop</option>
<option :value = 5>Return value of JavaScript command (start with 'return ')</option>
<option :value = 6>Return value of system command</option>
<option v-if="nowNode['isInLoop']" :value = 7>Return value of JavaScript command for the current loop item</option>
<option :value = 8>Return value of Python code under current environment</option>
</select>
<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 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 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".
2. Return the value of a custom global variable: `self.myVar`
3. Return the result of a conditional statement: `self.myVar == 1`
4. Determining whether the value extracted from a certain field is equal to the value of a certain variable: self.outputParameters["field name"] == self.myVar
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 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 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 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 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 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 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 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>
<option :value = 1>Random wait (set to wait for 10 seconds then it will randomly wait for 10 × 0.5 - 10 × 1.5 seconds)</option>
</select>
</div>
</div>
<!-- <button class="btn btn-outline-primary" style="margin-top: 20px;" id="confirm">Confirm</button>-->
</div>
</div>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Save Task (Can press Ctrl + S to open this modal)</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body" style="height:60vh;overflow: auto">
<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 spellcheck=false onkeydown="inputDelete(event)" required name="serviceName" value="New Web Crawler Task" id="serviceName" class="form-control"></input>
<label>Task Description:</label>
<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 file, recommended use CSV format when single cell exceeds 500 characters)</option>
<option value="csv">CSV (Recommended for collecting long articles)</option>
<option value="txt">TXT</option>
<option value="json">JSON</option>
<option value="mysql">MySQL Database (recommended for large amounts of data)</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 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>
<option value="2">Overwrite (If the file exists, overwrite it)</option>
</select>
<!-- <label>Is it an extreme anti-scraping website like Cloudflare (<a href="https://www.bilibili.com/video/BV1Ph4y1E7R9/" target="_blank">Watch Tutorial</a>)?</label>-->
<!-- <select id="cloudflare" name="cloudflare" class="form-control">-->
<!-- <option value=0>No</option>-->
<!-- <option value=1>Yes (Only support on Windows x64 platform)</option>-->
<!-- </select>-->
<label>Remove duplicates after execution (note that this function will be executed at the end of the task, and leaving the task midway will not perform deduplication):</label>
<select id="removeDuplicate" name="removeDuplicate" class="form-control">
<option value="0">No</option>
<option value="1">Yes</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 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>
<option value=1>Mobile</option>
</select>
<label>Whether to maximize the browser window:</label>
<select id="maximizeWindow" name="maximizeWindow" class="form-control">
<option value = 0>No</option>
<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 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 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 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 spellcheck=false onkeydown="inputDelete(event)" type="text" value="p" id="pauseKey" class="form-control"></input>
<input type="hidden" id="browser" name="browser" value="chrome"></input>
</div>
<div class="modal-footer">
<button type="button" id="saveAsButton" style="width: 100px" class="btn btn-outline-primary">Save as</button>
<button type="button" id="saveButton" style="width: 100px" class="btn btn-primary">Save</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal -->
</div>
</body>
<script src="FlowChart.js"></script>
<script src="global.js"></script>
<script src="logic.js"></script>
<script>
var navigator = new Vue({
el: '#navigator',
data: {
type: getUrlParam("type"),
backEndAddressServiceWrapper: getUrlParam("backEndAddressServiceWrapper"),
},
methods:{
gotoHome: function () {
let url = "";
if (getUrlParam("lang") == "zh") {
url = "taskList.html?lang=zh&type="+getUrlParam("type")+"&wsport="+getUrlParam("wsport")+"&backEndAddressServiceWrapper=" + this.backEndAddressServiceWrapper
} else {
url = "taskList.html?lang=en&type="+getUrlParam("type")+"&wsport="+getUrlParam("wsport")+"&backEndAddressServiceWrapper=" + this.backEndAddressServiceWrapper
}
window.location.href = url;
}, gotoInfo: function () {
let url = "";
if (getUrlParam("lang") == "zh") {
url = "taskInfo.html?id="+getUrlParam("id")+"&lang=zh&type="+getUrlParam("type")+"&wsport="+getUrlParam("wsport")+"&backEndAddressServiceWrapper=" + this.backEndAddressServiceWrapper
} else {
url = "taskInfo.html?id="+getUrlParam("id")+"&lang=en&type="+getUrlParam("type")+"&wsport="+getUrlParam("wsport")+"&backEndAddressServiceWrapper=" + this.backEndAddressServiceWrapper
}
window.location.href = url;
}
}
});
</script>
</html>