EasySpider/ElectronJS/src/taskGrid/FlowChart_CN.html
2023-12-14 12:02:35 +08:00

791 lines
75 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>设计流程</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">提示:保存成功!</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">提示:您加载的任务版本不是最新版,可能出现兼容性问题。</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">提示保存名不符合MySQL表名规范请重试</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 Modification~任务流程修改"
| 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;">工具箱</div>
<button type="button" id="save" data-toggle="modal" data-target="#myModal" onmousedown="$('#myModal').modal('show');" class="btn btn-primary">保存任务</button>
<button type="button" data=1 draggable="true" class="btn btn-outline-primary options">打开网页</button>
<button type="button" data=2 draggable="true" class="btn btn-outline-primary options">点击元素</button>
<button type="button" data=3 draggable="true" class="btn btn-outline-primary options">提取数据</button>
<button type="button" data=4 draggable="true" class="btn btn-outline-primary options">输入文字</button>
<button type="button" data=5 draggable="true" class="btn btn-outline-primary options" style="font-weight: bold">自定义操作</button>
<button type="button" data=6 draggable="true" style="font-size: 14px!important;" class="btn btn-outline-primary options">切换下拉选项</button>
<button type="button" data=7 draggable="true" class="btn btn-outline-primary options">移动到元素</button>
<button type="button" data=8 draggable="true" class="btn btn-outline-primary options" style="font-weight: bold">循环</button>
<button type="button" data=9 draggable="true" class="btn btn-outline-primary options" style="font-weight: bold">判断条件</button>
<div>----------</div>
<button type="button" data=13 draggable="true" class="btn btn-outline-primary options" title="调整下一个要插入的节点的位置">调整锚点</button>
<button type="button" data=10 class="btn btn-outline-primary options">剪切元素</button>
<button type="button" data=11 class="btn btn-outline-primary options">复制元素</button>
<button type="button" data=12 class="btn btn-outline-primary options">删除元素</button>
<button type="button" data=0 class="btn btn-outline-primary2 options">取消操作</button>
<div style="text-align: left;margin: 10px;font-size:15px!important">提示:拖动上方按钮到流程图箭头处以添加操作,也可以点击按钮再点击箭头。</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">等价XPath</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body">
<label>以下提供除默认生成的XPath外其余等价的XPath都能定位到同一个元素但不完全准确可能可以定位到除该元素外的其他元素因此只是提供在这里作为参考</label>
<label>每行一个XPath可使用预装的XPath Helper扩展调试</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>提示:鼠标移到笑脸可查看提示,在流程图中<b>双击</b>操作可试运行,<b>右键</b>点击操作查看更多选项。</label>
<label>选项名称</span></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>使用循环内的链接</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"'>链接池(每行一个链接,有多少行链接整个任务流程就会被执行多少次):</label>
<label v-else>链接(只能填写一个链接,因为是手动添加的打开网页操作):</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>页面加载最长等待时间(秒):</label>
<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>
<option :value = 1>向下滚动一屏</option>
<option :value = 2>滚动到底部</option>
<option :value = 3>一直滚动直到页面内容无变化(需设置好滚动后的等待时间用于检测页面变化)</option>
</select>
<label>滚动次数(滚动类型设置为<b>不滚动</b><b>一直滚动</b>时请忽略此项):</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>滚动后等待时间(秒):</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">
点此展开/折叠自定义操作
</a>
</p>
<div :class="{collapse: true, 'show': nowNode['parameters']['cookies'].length!=0}" id="collapseOpenPage">
<div>
<label>加载后设置Cookies </label>
<p style="margin-bottom: 20px;color:white"><a class="btn btn-primary" @click="getCookies">
点击获取当前页面Cookie
</a></p>
<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 spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内才显示此行元素 -->
<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 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 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>
<option :value = 1>JavaScript点击</option>
</select>
<label>在新标签页打开超链接:</label>
<select v-model='nowNode["parameters"]["newTab"]' class="form-control">
<option :value = 1></option>
<option :value = 0></option>
</select>
<label>点击后是否向下滚动页面:</label>
<select v-model='nowNode["parameters"]["scrollType"]' class="form-control">
<option :value = 0>不滚动</option>
<option :value = 1>向下滚动一屏</option>
<option :value = 2>滚动到底部</option>
<option :value = 3>一直滚动直到页面内容无变化(需设置好滚动后的等待时间用于检测页面变化)</option>
</select>
<label>滚动次数(滚动类型设置为<b>不滚动</b><b>一直滚动</b>时请忽略此项):</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>滚动后等待时间(秒):</label>
<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>
<option :value = 1>接受弹窗(点击弹窗确定按钮)</option>
<option :value = 2>拒绝弹窗点击弹窗取消按钮仅限Confirm弹框</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">
点此展开/折叠自定义操作
</a>
</p>
<div :class="{collapse: true, 'show': nowNode['parameters']['beforeJS'].length!=0 || nowNode['parameters']['afterJS'].length!=0}" id="collapseExample">
<div>
<label>点击该元素<strong></strong>针对该元素执行一段JavaScript脚本 </label>
<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 spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<label>点击该元素<strong></strong>针对该元素执行一段JavaScript脚本 </label>
<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 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= 'addPara'>新增字段</button>
</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>
<th>字段名</th>
<th style="width:200px">示例值</th>
<th>操作</th>
</tbody>
</table>
<table class="toolkittb4" cellspacing="0">
<tbody>
<tr v-for="i in paras.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='paras.parameters[i-1]["name"]'></input>
</td>
<td style="width:200px">{{paras.parameters[i-1]["exampleValues"][0]["value"]}}</td>
<td>
<a v-on:mousedown="modifyPara(i-1)">修改</a>
<a v-on:mousedown="deletePara(i-1)">删除</a>
<a v-on:mousedown="upPara(i-1)">上移</a>
<a v-on:mousedown="downPara(i-1)">下移</a>
</td>
</tr>
</table>
</div>
<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 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 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">
点此展开/折叠自定义操作
</a>
</p>
<div :class="{collapse: true, 'show': paras.parameters[paraIndex]['beforeJS'].length!=0 || paras.parameters[paraIndex]['afterJS'].length!=0}" id="elementAdvanced">
<div>
<div><a href="#" v-on:mousedown="trailPara(paraIndex)" style="text-decoration: none">试运行</a></div>
<label>提取该元素数据<strong></strong>针对该元素执行一段JavaScript脚本 </label>
<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 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 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 spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='paras.parameters[paraIndex]["afterJSWaitTime"]'></input>
</div>
</div>
<label>参数类型转换为用于Excel和数据库</label>
<select v-model='paras.parameters[paraIndex]["paraType"]' class="form-control">
<option value = "text">文本单个值长度预估超过1万请选择大文本</option>
<option value = "int">整数位数在9位以内</option>
<option value = "double">浮点数(小数)</option>
<option value = "mediumText">大文本单个值长度超过1万低于100万</option>
<option value = "datetime">日期时间</option>
<option value = "date">日期</option>
<option value = "time">时间</option>
<option value = "varchar">小文本单个值长度小于50</option>
<option value = "longText">超大文本单个值长度超过100万</option>
<option value = "bigInt">大整数位数超过9位</option>
</select>
<label>元素找不到时的值:</label>
<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>
<option :value = 1>文本(不包括子元素)</option>
<option :value = 2>innerHTML</option>
<option :value = 3>outerHTML</option>
<option :value = 4>背景图片地址</option>
<option :value = 5>页面网址</option>
<option :value = 6>页面标题</option>
<option :value = 7>元素截图</option>
<option :value = 8>OCR识别文字</option>
<option :value = 14>元素的属性值</option>
<option :value = 9>针对该元素的JavaScript代码返回值需以return 开头)</option>
<option :value = 12>系统命令返回值</option>
<option :value = 13>执行环境下的Python表达式值eval操作</option>
<option :value = 10>当前选择框选中的选项值</option>
<option :value = 11>当前选择框选中的选项文本</option>
</select>
<div v-if='paras.parameters[paraIndex]["contentType"] == 14'>
<label>属性名称:</label>
<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 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 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">
<option :value = 0>普通节点</option>
<option :value = 1>链接文本</option>
<option :value = 2>链接地址</option>
<option :value = 3>表单值</option>
<option :value = 4>图片地址</option>
</select>
<div v-if='paras.parameters[paraIndex]["nodeType"] == 4'>
<label>提取图片地址后是否同时<b>下载图片</b></label>
<select v-model='paras.parameters[paraIndex]["downloadPic"]' class="form-control">
<option :value = 0></option>
<option :value = 1></option>
</select>
</div>
<!-- <label>提取方式</label>-->
<!-- <select v-model='paras.parameters[paraIndex]["extractType"]' class="form-control">-->
<!-- <option :value = 0>普通提取</option>-->
<!-- <option :value = 1>OCR提取</option>-->
<!-- </select>-->
<label style="margin-top: 15px">是否保存该字段(只想把此字段当变量而不想保存时可选否):</label>
<select v-model='paras.parameters[paraIndex]["recordASField"]' class="form-control">
<option :value = 1></option>
<option :value = 0></option>
</select>
<label>参数描述:</label>
<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 spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用循环内的文本(不勾选则每次输入的文本为下方“输入值”文本框内的文本,勾选后会使用所在“文本列表”循环内设置的文本)</p>
<p v-if="useLoop">
<label>索引值0表示使用整个当前循环的文本如果大于0则表示当前文本用~来分割开的文本索引取值即如果当前循环的文本值为A~B则索引值为1表示输入A2表示输入B0表示输入A~B</label>
<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 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 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">
点此展开/折叠自定义操作
</a>
</p>
<div :class="{collapse: true, 'show': nowNode['parameters']['beforeJS'].length!=0 || nowNode['parameters']['afterJS'].length!=0}" id="inputAdvanced">
<div>
<label>对该元素输入文字<strong></strong>针对该元素执行一段JavaScript脚本 </label>
<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 spellcheck=false onkeydown="inputDelete(event)" required class="form-control" type="number" v-model.number='nowNode["parameters"]["beforeJSWaitTime"]'></input>
<label>对该元素输入文字<strong></strong>针对该元素执行一段JavaScript脚本 </label>
<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 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>操作在iframe内</p>
<label>执行模式</label>
<select v-model='codeMode' class="form-control" @change="handleCodeModeChange">
<option :value = 0>执行一段JavaScript脚本如要获得返回值则需以return 开头)</option>
<option :value = 1>执行一段操作系统级别命令</option>
<option v-if="nowNode['isInLoop']" :value = 2>针对当前循环项的JavaScript脚本</option>
<option v-if="nowNode['isInLoop']" :value = 3>退出当前循环Break操作</option>
<option v-if="nowNode['isInLoop']" :value = 4>跳过当前循环后面的操作Continue操作</option>
<option :value = 5>在执行环境下运行Python代码exec操作</option>
<option :value = 6>在执行环境下获得Python表达式值eval操作</option>
<option :value = 7>暂停程序执行(如检测到验证码框出现时暂停执行)</option>
<option :value = 8>刷新页面</option>
<option :value = 9>发送邮件</option>
</select>
<div v-if='nowNode["parameters"]["codeMode"] < 3 || nowNode["parameters"]["codeMode"] >= 5 && nowNode["parameters"]["codeMode"] <=6'>
<label>代码/脚本内容用Field["字段名"]来输入某字段/自定义操作的最新提取/返回值): </label>
<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不能在当前页面试运行只能在任务真正调用时运行。
此选项为高级功能可以直接用Python代码操纵正在运行中的浏览器及可以自定义整个执行环境中的变量并对变量进行修改赋值等操作示例
1. 用self.browser表示当前操作的浏览器可直接用selenium的API进行操作如self.browser.find_element(By.CSS_SELECTOR, "body").send_keys(Keys.END)即可滚动到页面最下方。
2. 自定义一个全局变量self.myVar = 1
3. 操纵上面定义的全局变量self.myVar = self.myVar + 1
4. 打印上面定义的全局变量print(self.myVar)
5. 将自定义变量的值赋值为某个字段提取的值self.myVar = self.outputParameters["字段名"]
如果想要将自己定义的变量作为字段记录请选择下一个“在执行环境下获得Python表达式值eval操作”选项。
6. 如果想要引入并使用程序本身没有带的第三方库需要先使用如pip等工具本地安装好此库然后在import之前添加自己安装的库的路径
1在系统命令行执行安装emotlib库命令
pip install emotlib
2在代码框中写入如下代码
sys.path.append("D:/Python38/Lib/site-packages") # 假设此路径下有emotlib库
import emotlib # 此时就可以使用emotlib库了
print(emotlib.emoji()) # 使用其中的函数。
</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'>请先阅读此说明再在上方输入框不是本框写具体代码如果要执行大量代码可以直接写outside:myCode.py这样程序就会读取并执行EasySpider目录下的myCode.py中的代码。
此选项为高级功能可以直接返回Python代码的表达式值并在其他位置用Field["本操作名称"]表示此操作返回值,示例:
1. 返回当前浏览器对象的相关值用self.browser表示当前操作的浏览器可直接用selenium的API进行操作如self.browser.find_element(By.CSS_SELECTOR, "body").text即可返回当前页面的文字。
2. 返回自定义全局变量的值self.myVar
3. 返回条件判断的值self.myVar == 1
4. 判断某个字段提取的值是否等于某个变量的值self.outputParameters["字段名"] == self.myVar
注意此功能不能对变量进行赋值操作即不可以写self.myVar = 1这种如果想要进行赋值操作请选择上一个“在执行环境下运行Python代码exec操作”选项。</pre>
<p style="margin-top: 15px">是否将执行后的输出/返回值作为字段记录:</p>
<p><select v-model='nowNode["parameters"]["recordASField"]' class="form-control">
<option :value = 0>仍可在任意操作中用Field["操作名"]表示此命令返回值)</option>
<option :value = 1>JavaScript脚本需要以return 开头)</option>
</select></p>
<p><label>参数类型转换为:</label>
<select v-model='nowNode["parameters"]["paraType"]' class="form-control">
<option value = "text">文本单个值长度预估超过1万请选择大文本</option>
<option value = "int">整数位数在9位以内</option>
<option value = "double">浮点数(小数)</option>
<option value = "mediumText">大文本单个值长度超过1万低于100万</option>
<option value = "datetime">日期时间</option>
<option value = "date">日期</option>
<option value = "time">时间</option>
<option value = "varchar">小文本单个值长度小于50</option>
<option value = "longText">超大文本单个值长度超过100万</option>
<option value = "bigInt">大整数位数超过9位</option>
</select>
</p>
<p>
<label>记录前清空其他操作字段已记录的值:</label>
<select v-model='nowNode["parameters"]["clear"]' class="form-control">
<option :value = 0></option>
<option :value = 1></option>
</select>
</p>
<p>
<label>此提取数据操作后生成新数据行:</label>
<select v-model='nowNode["parameters"]["newLine"]' class="form-control">
<option :value = 1></option>
<option :value = 0></option>
</select>
</p>
<label>最长等待脚本执行时间0代表无限等待 </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>此操作可以暂停程序执行,如检测到验证码框出现时暂停执行,直到手动长按键盘自定义暂停/继续快捷键默认p键后才继续执行。</label>
</div>
<div v-if='nowNode["parameters"]["codeMode"] == 8'>
<label>此操作可以刷新当前页面。</label>
</div>
<div v-if='nowNode["parameters"]["codeMode"] == 9'>
<label>此操作可以发送邮件,如用于爬虫任务完成后发送邮件通知。</label>
<label>STMP邮件服务器主机</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["host"]' placeholder="如smtp.163.com"></input>
<label>邮件服务器端口:</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["port"]' placeholder="如465"></input>
<label>发件人邮箱用户名:</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["username"]'></input>
<label>发件人邮箱密码(设置了密码注意不要轻易泄露任务文件!):</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["password"]' placeholder="多数邮箱服务器为授权码而不是原密码"></input>
<label>收件人邮箱地址:</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["to"]' placeholder="多个收件人用英文逗号隔开"></input>
<label>邮件主题:</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model='nowNode["parameters"]["emailConfig"]["subject"]' placeholder="这里写邮件主题"></input>
<label>邮件内容:</label>
<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 spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='nowNode["parameters"]["iframe"]'></input>元素在iframe内</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内且循环内是固定文本才显示此行元素 -->
<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 spellcheck=false onkeydown="inputDelete(event)" class="form-control" type="number" v-model.number='nowNode["parameters"]["index"]'></input></p>
</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">点此查看其他等价的XPath</button></p>
<div v-if="!useLoop">
<p>切换模式</p>
<select class="form-control" v-model='nowNode["parameters"]["optionMode"]'>
<option :value=0>切换到下一个选项</option>
<option :value=1>按索引值切换选项第一个选项索引值为0</option>
<option :value=2>按选项值切换选项</option>
<option :value=3>按选项文本切换选项</option>
</select>
<p>设定值(不适用于切换到下一个选项模式)</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>元素在iframe内</p>
<div v-if="nowNode['isInLoop']">
<!-- 如果在循环内才显示此行元素 -->
<p><input spellcheck=false onkeydown="inputDelete(event)" type="checkbox" v-model='useLoop'></input>使用相对循环内的XPath定位的元素</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">点此查看其他等价的XPath</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>在iframe内操作</p>
<!-- 循环选项 -->
<label>循环类型:</label>
<select v-model='loopType' class="form-control" @change="handleLoopTypeChange">
<option :value = 0>单个元素(多用于循环点击下一页)</option>
<option :value = 1>不固定元素列表</option>
<option :value = 2>固定元素列表</option>
<option :value = 3>文本列表(多用于循环在文本框输入文本)</option>
<option :value = 4>网址列表(多用于循环打开网页)</option>
<option :value = 5>JavaScript命令返回值需以return 开头)</option>
<option :value = 6>系统命令返回值</option>
<option :value = 7>执行环境下的Python表达式值eval操作</option>
</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 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 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 spellcheck=false onkeydown="inputDelete(event)" class="form-control" rows="3" placeholder="每行一个文本/网址,用~来分割文字即如果某行值为A~B则在输入文字操作中可以设定索引值为1表示输入A2表示输入B0表示输入A~B" v-model='nowNode["parameters"]["textList"]'></textarea>
</div>
<div v-else-if='parseInt(loopType) < 8'>
<label>代码/脚本内容用Field["字段名"]来输入某字段/自定义操作的最新提取/返回值): </label>
<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这个文本。
2. 返回自定义全局变量的值self.myVar如果
3. 返回条件判断的值self.myVar == 1
4. 判断某个字段提取的值是否等于某个变量的值self.outputParameters["字段名"] == self.myVar
以上表达式返回值大于0或为真则继续循环否则停止循环。
</pre>
<label>最长等待脚本执行时间0代表无限等待 </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>最多执行循环次数0代表无限循环直到找不到元素或检测不到页面元素内容变化为止</label>
<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 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>(自定义操作)使用代码/脚本定义循环退出条件(也可以在流程中添加<b>自定义操作</b>,然后选择<b>退出循环</b>选项): </label></p>
<select v-model='nowNode["parameters"]["breakMode"]' class="form-control" style="font-weight: bold">
<option :value = 0>不设置脚本(选择这个下面写了脚本也不会执行)</option>
<option :value = 1>JavaScript脚本返回值需以return 开头)</option>
<option :value = 2>操作系统级别命令</option>
</select>
<div>
<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 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 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>
<option :value = 1>向下滚动一屏</option>
<option :value = 2>滚动到底部</option>
<option :value = 3>一直滚动直到页面内容无变化(需设置好滚动后的等待时间用于检测页面变化)</option>
</select>
<label>滚动次数(滚动类型设置为<b>不滚动</b><b>一直滚动</b>时请忽略此项):</label>
<input spellcheck=false onkeydown="inputDelete(event)" class="form-control" v-model.number="nowNode['parameters']['scrollCount']" type="number" required></input>
<label>滚动后等待时间(秒):</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>判断条件是从左往右判断的,即如果最左边的条件分支的判断条件满足,则执行最左边分支内的操作,否则判断从左向右第二个分支的条件是否满足,以此类推。设计任务时点击分支即可在浏览器中<b>动态调试</b>分支是否满足不适用于系统命令和Python Eval操作</label>
</div>
<div class="elements" v-if="nodeType==10">
<label>判断条件是从左往右判断的,即如果最左边的条件分支的判断条件满足,则执行最左边分支内的操作,否则判断从左向右第二个分支的条件是否满足,以此类推。设计任务时点击分支即可在浏览器中<b>动态调试</b>分支是否满足不适用于系统命令和Python Eval操作</label>
<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>
<option :value = 1>当前页面包括文本</option>
<option :value = 2>当前页面包括元素</option>
<option v-if="nowNode['isInLoop']" :value = 3>当前循环项包括文本</option>
<option v-if="nowNode['isInLoop']" :value = 4>当前循环项包括元素</option>
<option :value = 5>JavaScript命令返回值需以return 开头)</option>
<option :value = 6>系统命令返回值</option>
<option v-if="nowNode['isInLoop']" :value = 7>针对当前循环项的JavaScript命令返回值需以return 开头)</option>
<option :value = 8>执行环境下的Python表达式值eval操作</option>
</select>
<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 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 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这个文本。
2. 返回自定义全局变量的值self.myVar如果
3. 返回条件判断的值self.myVar == 1
4. 判断某个字段提取的值是否等于某个变量的值self.outputParameters["字段名"] == self.myVar
以上表达式返回值大于0或为则执行此分支内操作否则不执行。
</pre>
<label>最长等待脚本执行时间0代表无限等待 </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>代码/脚本内容(<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 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 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 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 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 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 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>
<option :value = 1>随机等待设置等10秒会随机等10×0.5 - 10 × 1.5 秒)</option>
</select>
</div>
</div>
<!-- <button class="btn btn-outline-primary" style="margin-top: 20px;" id="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">保存任务可按Ctrl+S调出此窗口</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>任务名称:</label>
<input spellcheck=false onkeydown="inputDelete(event)" required name="serviceName" value="新web采集任务" id="serviceName" class="form-control"></input>
<label>任务描述:</label>
<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>
<option value = "csv">CSV</option>
<option value = "txt">TXT</option>
<option value = "json">JSON</option>
<option value = "mysql">MySQL数据库</option>
</select>
<label>导出文件名/数据库表格名称(可使用../表示相对路径以改变文件保存位置名称中的“current_time”会被替换为执行任务时的时间戳</label>
<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>
<option value=2>覆盖写入(如果文件已存在则覆盖原文件)</option>
</select>
<!-- <label>是否为Cloudflare等极端反爬网站<a href="https://www.bilibili.com/video/BV1Ph4y1E7R9/" target="_blank">查看Cloudflare设计和执行教程</a></label>-->
<!-- <select id="cloudflare" name="cloudflare" class="form-control">-->
<!-- <option value = 0>否</option>-->
<!-- <option value = 1>是只支持Windows x64系统</option>-->
<!-- </select>-->
<label>执行时通过读取以下Excel.xlsx文件来修改各个操作的输入参数文件格式请在调用任务时点击“从Excel文件读取输入参数”按钮查看</label>
<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>
<option value = 1>手机端</option>
</select>
<label>是否最大化浏览器窗口:</label>
<select id="maximizeWindow" name="maximizeWindow" class="form-control">
<option value = 0></option>
<option value = 1></option>
</select>
<label>每采集多少条数据保存一次(值越大采集速度越快,但如果意外退出则有数据丢失风险):</label>
<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 spellcheck=false onkeydown="inputDelete(event)" type="number" value="60" id="quitWaitTime" name="quitWaitTime" class="form-control"></input>
<label>控制台预览时数据最大显示长度:</label>
<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 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">另存为</button>
<button type="button" id="saveButton" style="width: 100px" class="btn btn-primary">保存</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>