From d4f89ddc13087a6b65e8abcf38db5a4733269bae Mon Sep 17 00:00:00 2001 From: naibo Date: Sun, 20 Aug 2023 21:09:13 +0800 Subject: [PATCH] Update Readme --- .../execution_instances/28.json | 1 + .temp_to_pub/EasySpider_windows_x64/info.log | 222 ++++++++++++++++++ .../EasySpider_windows_x64/tasks/212.json | 1 + ElectronJS/README.md | 29 ++- ElectronJS/execute_win32.bat | 11 + ElectronJS/{execute.bat => execute_win64.bat} | 0 ElectronJS/update_chrome.py | 4 +- ExecuteStage/Readme.md | 23 +- Extension/README.md | 21 +- 9 files changed, 293 insertions(+), 19 deletions(-) create mode 100644 .temp_to_pub/EasySpider_windows_x64/execution_instances/28.json create mode 100644 .temp_to_pub/EasySpider_windows_x64/tasks/212.json create mode 100644 ElectronJS/execute_win32.bat rename ElectronJS/{execute.bat => execute_win64.bat} (100%) diff --git a/.temp_to_pub/EasySpider_windows_x64/execution_instances/28.json b/.temp_to_pub/EasySpider_windows_x64/execution_instances/28.json new file mode 100644 index 0000000..8566f0f --- /dev/null +++ b/.temp_to_pub/EasySpider_windows_x64/execution_instances/28.json @@ -0,0 +1 @@ +{"id":28,"name":"京东全球版-专业的综合网上购物商城","url":"https://www.jd.com","links":"https://www.jd.com","create_time":"8/19/2023, 2:38:26 PM","update_time":"8/19/2023, 2:38:26 PM","version":"0.5.0","saveThreshold":10,"cloudflare":0,"environment":0,"maxViewLength":15,"recordLog":1,"outputFormat":"xlsx","saveName":"current_time","inputExcel":"","startFromExit":0,"containJudge":false,"desc":"https://www.jd.com","inputParameters":[{"id":0,"name":"urlList_0","nodeId":1,"nodeName":"打开网页","value":"https://www.jd.com","desc":"要采集的网址列表,多行以\\n分开","type":"text","exampleValue":"https://www.jd.com"}],"outputParameters":[{"id":0,"name":"参数1_文本","desc":"","type":"text","recordASField":1,"exampleValue":"\n \n \n \n \n \n 京东首页\n \t\t\t\t\t\t\t\t\t\t\t海外 \t\t\t\t\t\t\t\t\t\t\t\t\t\t \t\t\t\t\t北京上海天津重庆河北山西河南辽宁吉林黑龙江内蒙古江苏山东安徽浙江福建湖北湖南广东广西江西四川海南贵州云南西藏陕西甘肃青海宁夏新疆港澳台湾钓鱼岛海外 \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t 地区专享版本 \t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t中國港澳 \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t中國台灣 \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t京东全球 \t\t\t\t\t \t\t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t Available Sites \t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tGlobal Site \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tСайт России \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tSitus Indonesia \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tSitio de España \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t เว็บไซต์ประเทศไทย \t\t\t\t\t\t \t\t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t\t\n \n \n 你好,请登录  免费注册\n \n \n \n 我的订单\n \n \n \n \n \n 我的京东\n \n \n \n \n \n \n 京东会员\n \n \n \n \n \n 企业采购\n \n \n \n \n \n 客户服务\n \n \n \n \n \n \n 网站导航\n \n \n \n \n \n \n 手机京东\n \n \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n 网站无障碍\n \n \n \n \n \n \n\n \n \n \n (function (window) {\n window.data = window.data || {}\n window.data['cms_header'] = {\n setting: [{\"NAME\":\"手机\",\"URL\":\"//\",\"ANCHOR\":\"\",\"property\":\"\",\"CUSTOM1\":\"#050505\",\"CUSTOM2\":\"\",\"CUSTOM3\":\"\"}]\n }\n })(window)\n \n \n #search-2014 .text {border-color: #050505;}#search-2014 .button {background: #050505;} 京东 手机 全部分类◇ 搜索 >0 我的购物车 \n \n\n \n\n \n \n 顶通组件占位手机分类热门推荐苹果华为荣耀小米vivoOPPO运营商手机卡营业厅充话费配件充电器数据线手机壳贴膜移动电源创意配件热门分类全部手机5G手机苹果 iPhone 11iPhone XS Max华为Mate40 Pro 4Gnova 8 Pro 无充Nova8SE 乐活版Mate 40 RSNova 9P50 Pro 4G华为智选手机荣耀荣耀V30 PRO荣耀30 Pro荣耀X10 Max荣耀Play4 Pro小米小米10Redmi K30vivoS10 ProX60Y70t iQOO 8 iQOO Neo5 iQOO Z3OPPOReno 6OPPO K9 Find X3品牌中国移动中国联通中国电信精选店铺京东通信北京移动广东移动宽带专区50M300M优选品牌Anker罗马仕品胜倍思绿联亿色毕亚兹斯泰克热卖爆款移动电源原装充电器散热背夹扩展坞苹果数据线氮化镓Type C信号放大器手游周边王者荣耀手机散热器吃鸡神器弯头线游戏手柄王座同屏器新奇好物氮化镓PD快充双向快充创意配件配件频道海量配件低至9.包邮机身存储16GB8GB4GB分辨率全高清FHD+高清HD+屏幕尺寸5.0英寸及以下5.0~5.49英寸5.5~5.99英寸6.0~6.24英寸有新机游戏手机手机营业厅手机好店以旧换新企业购热卖推荐人气新品限时特惠配件专区飞利浦(PHILIPS)真无线领夹麦克风小蜜蜂收音器直播vlog拍视频采访话筒设备手机通用DLM3540C¥199.00JBL音乐唱将KMC600无线麦克风蓝牙话筒音响一体麦克风全民/K歌 儿童K歌宝话筒家庭ktv玫瑰金¥599.00声阔Soundcore超能小彩蛋 LifeP3主动降噪真无线TWS入耳式蓝牙耳机适用苹果/华为/小米手机蓝30H续航版¥399.00漫步者(EDIFIER)W820NB经典版 头戴蓝牙主动降噪耳机 金标认证 手机电脑笔记本耳机 七夕情人节礼物 云岩白¥269.00\n \n \n\n \n \n \n\n \n\n \n \n window.pageConfig = window.pageConfig || {}\n window.pageConfig.o2JSConfig = {\n useTplInJs: true,\n pathRule: function (path) {\n return '//static.360buyimg.com/mtd/pc/cms' + '/floors/' + path + '.min.js'\n }\n }\n \n seajs.use(['//static.360buyimg.com/mtd/pc/base/1.0.1/channel.js'])\n \n seajs.use(['//wl.jd.com/wl.js'])\n \n \n \n !(function () {\n var testObject = {}\n if (!(Object.setPrototypeOf || testObject.__proto__)) {\n var nativeGetPrototypeOf = Object.getPrototypeOf\n Object.getPrototypeOf = function (object) {\n return object.__proto__ || nativeGetPrototypeOf.call(Object, object)\n }\n }\n })()\n \n \n \n \n \n \n // nerv-create-class 用 'nervjs'\n window.nervjs = Nerv\n // nerv-create-class\n !(function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e(require(\"nervjs\")):\"function\"==typeof define&&define.amd?define([\"nervjs\"],e):t.NervCreateClass=e(t.nervjs)})(this,(function(t){\"use strict\";function e(t){return t===undefined||null===t}function n(){}function r(t){return\"function\"==typeof t}function o(t){return t===undefined}function i(t,n){for(var r in n)e(n[r])||(t[r]=n[r]);return t}function a(t){for(var e in t){var n=t[e];\"function\"!=typeof n||n.__bound||1===g[e]||((t[e]=n.bind(t)).__bound=!0)}}function c(t,e){void 0===e&&(e={});for(var n=0,r=t.length;n wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n func.apply(context, args);\n } else if (!timeout) {\n timeout = setTimeout(later, remaining);\n }\n };\n return throttled;\n }\n // Context\n var LingAtomScrollContext = Nerv.createContext({\n scrollTop: 0,\n windowHeight: 0,\n bodyHeight: 0\n })\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n function genComponentElement (type, props, children) {\n \n return Nerv.createElement(\n Lc[type] ? Lc[type].component : 'div',\n props,\n children\n )\n \n }\n \n \n window.Lc = window.Lc || {}\n Lc['Page'] = { component: 'div' }\n \n \n function EventEmitter () {\n var eventEmitterPool = {}\n var eventEmitter = {\n on: function (eventName, handler) {\n eventEmitterPool[eventName] = eventEmitterPool[eventName] || []\n eventEmitterPool[eventName].push(handler)\n },\n trigger: function (eventName) {\n var handlers = eventEmitterPool[eventName] || []\n var args = Array.prototype.slice.call(arguments, 1)\n for (var i = 0; i < handlers.length; i++) {\n handlers[i].apply(this, args)\n }\n },\n off: function (eventName, handler) {\n if (!eventEmitterPool[eventName]) return\n if (!handler) {\n eventEmitterPool[eventName] = []\n return\n }\n var handlers = eventEmitterPool[eventName] || []\n for (var i = 0; i < handlers.length; i++) {\n if (handlers[i] === handler) {\n eventEmitterPool[eventName].splice(i, 1)\n break\n }\n }\n }\n }\n return eventEmitter\n }\n var eventEmitter = EventEmitter()\n\n !function () {\n var downloadedBundles = [\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a6__5ee34e5afc685b3ecdd0f087.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a7__5ee34e58fc685b3ecdd0f078.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a8__5ee34e5afc685b3ecdd0f08a.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a9__5fa90cbc7e292cb70199df98.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd594__5ee34e59fc685b3ecdd0f07e.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5aa__5ee34e5bfc685b3ecdd0f094.js\"]\n var body = document.body || document.documentElement\n var Wrap = function (props) {\n return props.children\n }\n // Lazyload Component\n var LazyLoadComponent = NervCreateClass({\n // loading loaded\n status: '',\n getInitialState: function () {\n return {\n status: 'initial'\n }\n },\n updateOffsetTop: function () {\n if (this.state.status !== 'initial') return\n var node = Nerv.findDOMNode(this)\n var rect = node.getBoundingClientRect()\n var winHeight = this.props.__context.windowHeight\n var canLoad = rect.top < winHeight * 1.5 && rect.top + rect.height > -winHeight * 0.5\n if (canLoad) {\n this.downloadScript()\n }\n },\n delayLoaded: function () {\n var that = this\n setTimeout(function () {\n that.setState({ status: 'loaded' })\n }, 500)\n },\n downloadScript: function () {\n var that = this\n var myItem = this.props.item\n if (!myItem.reactBundle || downloadedBundles.indexOf(myItem.reactBundle) !== -1) {\n if (Lc[myItem.type]) {\n this.setState({ status: 'loading' })\n this.delayLoaded()\n } else {\n eventEmitter.on(myItem.type, function () {\n that.setState({ status: 'loading' })\n that.delayLoaded()\n })\n }\n return\n }\n myItem.reactBundle = myItem.reactBundle && myItem.reactBundle.replace('storage.jd.com', 'storage.360buyimg.com')\n downloadedBundles.push(myItem.reactBundle)\n var element = document.createElement('script')\n element.src = myItem.reactBundle\n element.charset = 'UTF-8'\n body.appendChild(element)\n element.onload = function () {\n that.setState({ status: 'loading' })\n that.delayLoaded()\n eventEmitter.trigger(myItem.type)\n }\n },\n componentDidMount: function () {\n this.updateOffsetTop()\n },\n componentWillReceiveProps: function (nextProps) {\n this.updateOffsetTop()\n },\n shouldComponentUpdate: function (nextProps, nextState) {\n return this.state.status !== nextState.status\n },\n componentDidCatch: function (error, info) {\n // console.log(error)\n // 上报组件渲染错误\n // @see //talos30011-prelb.o2athena.svc.n.jd.local/api-docs#null%2Fpaths%2F~1report%2Fpost\n var xhr = new XMLHttpRequest()\n xhr.open('POST', 'https://atom-log.3.cn/report', true)\n xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')\n xhr.send('platform=h5&url=' + location.href + '&cname=' + this.props.item.type + '&project=' + globalData.projectId)\n },\n getWrappedElement: function (extraProps) {\n if (this.WrappedElement) {\n return this.WrappedElement\n }\n var item = this.props.item\n var children = item.props.content || this.props.children || null\n var WrappedElement = genComponentElement(item.type, Object.assign({}, item.props, extraProps), children)\n this.WrappedElement = WrappedElement\n return WrappedElement\n },\n render: function () {\n var that = this\n var status = this.state.status\n // if (status === 'initial' || status === 'loading') {\n if (status === 'initial') {\n return Nerv.createElement(\n 'div',\n {\n style: {\n padding: '10px',\n backgroundClip: 'content-box',\n minHeight: '256px',\n height: '100%',\n backgroundColor: '#e3e4e5'\n }\n }\n // status === 'loading' ?\n // Nerv.createElement(\n // 'div',\n // {\n // style: {\n // width: 0,\n // height: 0,\n // overflow: 'hidden'\n // }\n // },\n // that.getWrappedElement()\n // ) : null\n )\n } else {\n // return that.getWrappedElement()\n // 缺点是多了一层 div\n this.cc = this.cc || that.getWrappedElement()\n return Nerv.createElement(\n 'div',\n status === 'loading' ? {\n style: {\n padding: '10px',\n backgroundClip: 'content-box',\n minHeight: '256px',\n height: '100%',\n backgroundColor: '#e3e4e5'\n }\n } : {},\n this.cc\n )\n }\n }\n })\n\n function createTree (tree) {\n tree = tree.filter(function (item) {\n return item.isShow === undefined || item.isShow === true\n })\n\n return tree.map(function (item) {\n var hasChildren = item.childrens && item.childrens.length\n hasChildren && (item.props.children = createTree(item.childrens))\n if (hasChildren) {\n return genComponentElement(item.type, item.props, item.props.content)\n } else {\n return Nerv.createElement(\n LingAtomScrollContext.Consumer,\n {},\n function (context) {\n return Nerv.createElement(\n LazyLoadComponent,\n {\n item: item,\n __context: context\n }\n )\n }\n )\n }\n })\n }\n\n var App = NervCreateClass({\n getInitialState: function () {\n return {\n scrollTop: 0,\n windowHeight: window.innerHeight,\n bodyHeight: document.body.clientHeight\n }\n },\n componentDidMount: function () {\n var that = this\n window.onscroll = throttle(function () {\n var bodyScrollHeight = document.documentElement.scrollTop || document.body.scrollTop\n that.setState({\n scrollTop: bodyScrollHeight\n })\n }, 200)\n window.onresize = function () {\n var windowInnerHeight = window.innerHeight\n if (windowInnerHeight === that.state.windowHeight) return\n that.setState({\n windowHeight: windowInnerHeight\n })\n }\n function onElementHeightChange (elm, callback) {\n var lastHeight = elm.clientHeight\n var newHeight\n (function run () {\n newHeight = elm.clientHeight\n if (lastHeight !== newHeight) {\n callback(newHeight)\n }\n lastHeight = newHeight\n if (elm.onElementHeightChangeTimer) {\n clearTimeout(elm.onElementHeightChangeTimer)\n }\n elm.onElementHeightChangeTimer = setTimeout(run, 200)\n })()\n }\n onElementHeightChange(document.body, function (h) {\n that.setState({ bodyHeight: h })\n })\n },\n render: function () {\n return Nerv.createElement(\n LingAtomScrollContext.Provider,\n {\n value: this.state\n },\n createTree(window.o2PageConfig.data)\n )\n }\n })\n\n Nerv.render(\n Nerv.createElement(App),\n document.querySelector('#app')\n )\n }()\n \n \n\n\n\n\n ✖ ✍操作台(点此拖动,左上角调整大小) \n ● 已选中1个元素,您可以:\n 确认采集 取消选择 Path: /html/body \n"}],"graph":[{"index":0,"id":0,"parentId":0,"type":-1,"option":0,"title":"root","sequence":[1,2],"parameters":{"history":1,"tabIndex":0,"useLoop":false,"xpath":"","iframe":false,"wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0},"isInLoop":false},{"id":1,"index":1,"parentId":0,"type":0,"option":1,"title":"打开网页","sequence":[],"isInLoop":false,"position":0,"parameters":{"useLoop":false,"xpath":"","wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"url":"https://www.jd.com","links":"https://www.jd.com","maxWaitTime":10,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"cookies":""}},{"id":2,"index":2,"parentId":0,"type":1,"option":8,"title":"循环","sequence":[3,5],"isInLoop":false,"position":1,"parameters":{"history":4,"tabIndex":-1,"useLoop":false,"xpath":"/html/body/div[5]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div/a","iframe":false,"wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"loopType":1,"pathList":"","textList":"","code":"","waitTime":0,"exitCount":0,"historyWait":2,"breakMode":0,"breakCode":"","breakCodeWaitTime":0,"allXPaths":""}},{"id":3,"index":3,"parentId":2,"type":0,"option":2,"title":"点击元素","sequence":[],"isInLoop":true,"position":0,"parameters":{"history":4,"tabIndex":-1,"useLoop":true,"xpath":"","iframe":false,"wait":2,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"clickWay":0,"maxWaitTime":10,"paras":[],"allXPaths":"","loopType":1}},{"id":-1,"index":4,"parentId":2,"type":0,"option":2,"title":"点击元素","sequence":[],"isInLoop":true,"position":1,"parameters":{"history":5,"tabIndex":-1,"useLoop":false,"xpath":"/html/body","iframe":false,"wait":2,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"clickWay":0,"maxWaitTime":10,"paras":[],"allXPaths":["/html/body","//body[contains(., '')]","/html/body"]}},{"id":4,"index":5,"parentId":2,"type":0,"option":3,"title":"提取数据","sequence":[],"isInLoop":true,"position":1,"parameters":{"history":5,"tabIndex":-1,"useLoop":false,"xpath":"","iframe":false,"wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"clear":0,"paras":[{"nodeType":0,"contentType":0,"relative":false,"name":"参数1_文本","desc":"","extractType":0,"relativeXPath":"/html/body","allXPaths":["/html/body","//body[contains(., '')]","/html/body"],"exampleValues":[{"num":0,"value":"\n \n \n \n \n \n 京东首页\n \t\t\t\t\t\t\t\t\t\t\t海外 \t\t\t\t\t\t\t\t\t\t\t\t\t\t \t\t\t\t\t北京上海天津重庆河北山西河南辽宁吉林黑龙江内蒙古江苏山东安徽浙江福建湖北湖南广东广西江西四川海南贵州云南西藏陕西甘肃青海宁夏新疆港澳台湾钓鱼岛海外 \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t 地区专享版本 \t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t中國港澳 \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t中國台灣 \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t京东全球 \t\t\t\t\t \t\t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t Available Sites \t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tGlobal Site \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tСайт России \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tSitus Indonesia \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tSitio de España \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t เว็บไซต์ประเทศไทย \t\t\t\t\t\t \t\t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t\t\n \n \n 你好,请登录  免费注册\n \n \n \n 我的订单\n \n \n \n \n \n 我的京东\n \n \n \n \n \n \n 京东会员\n \n \n \n \n \n 企业采购\n \n \n \n \n \n 客户服务\n \n \n \n \n \n \n 网站导航\n \n \n \n \n \n \n 手机京东\n \n \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n 网站无障碍\n \n \n \n \n \n \n\n \n \n \n (function (window) {\n window.data = window.data || {}\n window.data['cms_header'] = {\n setting: [{\"NAME\":\"手机\",\"URL\":\"//\",\"ANCHOR\":\"\",\"property\":\"\",\"CUSTOM1\":\"#050505\",\"CUSTOM2\":\"\",\"CUSTOM3\":\"\"}]\n }\n })(window)\n \n \n #search-2014 .text {border-color: #050505;}#search-2014 .button {background: #050505;} 京东 手机 全部分类◇ 搜索 >0 我的购物车 \n \n\n \n\n \n \n 顶通组件占位手机分类热门推荐苹果华为荣耀小米vivoOPPO运营商手机卡营业厅充话费配件充电器数据线手机壳贴膜移动电源创意配件热门分类全部手机5G手机苹果 iPhone 11iPhone XS Max华为Mate40 Pro 4Gnova 8 Pro 无充Nova8SE 乐活版Mate 40 RSNova 9P50 Pro 4G华为智选手机荣耀荣耀V30 PRO荣耀30 Pro荣耀X10 Max荣耀Play4 Pro小米小米10Redmi K30vivoS10 ProX60Y70t iQOO 8 iQOO Neo5 iQOO Z3OPPOReno 6OPPO K9 Find X3品牌中国移动中国联通中国电信精选店铺京东通信北京移动广东移动宽带专区50M300M优选品牌Anker罗马仕品胜倍思绿联亿色毕亚兹斯泰克热卖爆款移动电源原装充电器散热背夹扩展坞苹果数据线氮化镓Type C信号放大器手游周边王者荣耀手机散热器吃鸡神器弯头线游戏手柄王座同屏器新奇好物氮化镓PD快充双向快充创意配件配件频道海量配件低至9.包邮机身存储16GB8GB4GB分辨率全高清FHD+高清HD+屏幕尺寸5.0英寸及以下5.0~5.49英寸5.5~5.99英寸6.0~6.24英寸有新机游戏手机手机营业厅手机好店以旧换新企业购热卖推荐人气新品限时特惠配件专区飞利浦(PHILIPS)真无线领夹麦克风小蜜蜂收音器直播vlog拍视频采访话筒设备手机通用DLM3540C¥199.00JBL音乐唱将KMC600无线麦克风蓝牙话筒音响一体麦克风全民/K歌 儿童K歌宝话筒家庭ktv玫瑰金¥599.00声阔Soundcore超能小彩蛋 LifeP3主动降噪真无线TWS入耳式蓝牙耳机适用苹果/华为/小米手机蓝30H续航版¥399.00漫步者(EDIFIER)W820NB经典版 头戴蓝牙主动降噪耳机 金标认证 手机电脑笔记本耳机 七夕情人节礼物 云岩白¥269.00\n \n \n\n \n \n \n\n \n\n \n \n window.pageConfig = window.pageConfig || {}\n window.pageConfig.o2JSConfig = {\n useTplInJs: true,\n pathRule: function (path) {\n return '//static.360buyimg.com/mtd/pc/cms' + '/floors/' + path + '.min.js'\n }\n }\n \n seajs.use(['//static.360buyimg.com/mtd/pc/base/1.0.1/channel.js'])\n \n seajs.use(['//wl.jd.com/wl.js'])\n \n \n \n !(function () {\n var testObject = {}\n if (!(Object.setPrototypeOf || testObject.__proto__)) {\n var nativeGetPrototypeOf = Object.getPrototypeOf\n Object.getPrototypeOf = function (object) {\n return object.__proto__ || nativeGetPrototypeOf.call(Object, object)\n }\n }\n })()\n \n \n \n \n \n \n // nerv-create-class 用 'nervjs'\n window.nervjs = Nerv\n // nerv-create-class\n !(function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e(require(\"nervjs\")):\"function\"==typeof define&&define.amd?define([\"nervjs\"],e):t.NervCreateClass=e(t.nervjs)})(this,(function(t){\"use strict\";function e(t){return t===undefined||null===t}function n(){}function r(t){return\"function\"==typeof t}function o(t){return t===undefined}function i(t,n){for(var r in n)e(n[r])||(t[r]=n[r]);return t}function a(t){for(var e in t){var n=t[e];\"function\"!=typeof n||n.__bound||1===g[e]||((t[e]=n.bind(t)).__bound=!0)}}function c(t,e){void 0===e&&(e={});for(var n=0,r=t.length;n wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n func.apply(context, args);\n } else if (!timeout) {\n timeout = setTimeout(later, remaining);\n }\n };\n return throttled;\n }\n // Context\n var LingAtomScrollContext = Nerv.createContext({\n scrollTop: 0,\n windowHeight: 0,\n bodyHeight: 0\n })\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n function genComponentElement (type, props, children) {\n \n return Nerv.createElement(\n Lc[type] ? Lc[type].component : 'div',\n props,\n children\n )\n \n }\n \n \n window.Lc = window.Lc || {}\n Lc['Page'] = { component: 'div' }\n \n \n function EventEmitter () {\n var eventEmitterPool = {}\n var eventEmitter = {\n on: function (eventName, handler) {\n eventEmitterPool[eventName] = eventEmitterPool[eventName] || []\n eventEmitterPool[eventName].push(handler)\n },\n trigger: function (eventName) {\n var handlers = eventEmitterPool[eventName] || []\n var args = Array.prototype.slice.call(arguments, 1)\n for (var i = 0; i < handlers.length; i++) {\n handlers[i].apply(this, args)\n }\n },\n off: function (eventName, handler) {\n if (!eventEmitterPool[eventName]) return\n if (!handler) {\n eventEmitterPool[eventName] = []\n return\n }\n var handlers = eventEmitterPool[eventName] || []\n for (var i = 0; i < handlers.length; i++) {\n if (handlers[i] === handler) {\n eventEmitterPool[eventName].splice(i, 1)\n break\n }\n }\n }\n }\n return eventEmitter\n }\n var eventEmitter = EventEmitter()\n\n !function () {\n var downloadedBundles = [\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a6__5ee34e5afc685b3ecdd0f087.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a7__5ee34e58fc685b3ecdd0f078.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a8__5ee34e5afc685b3ecdd0f08a.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a9__5fa90cbc7e292cb70199df98.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd594__5ee34e59fc685b3ecdd0f07e.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5aa__5ee34e5bfc685b3ecdd0f094.js\"]\n var body = document.body || document.documentElement\n var Wrap = function (props) {\n return props.children\n }\n // Lazyload Component\n var LazyLoadComponent = NervCreateClass({\n // loading loaded\n status: '',\n getInitialState: function () {\n return {\n status: 'initial'\n }\n },\n updateOffsetTop: function () {\n if (this.state.status !== 'initial') return\n var node = Nerv.findDOMNode(this)\n var rect = node.getBoundingClientRect()\n var winHeight = this.props.__context.windowHeight\n var canLoad = rect.top < winHeight * 1.5 && rect.top + rect.height > -winHeight * 0.5\n if (canLoad) {\n this.downloadScript()\n }\n },\n delayLoaded: function () {\n var that = this\n setTimeout(function () {\n that.setState({ status: 'loaded' })\n }, 500)\n },\n downloadScript: function () {\n var that = this\n var myItem = this.props.item\n if (!myItem.reactBundle || downloadedBundles.indexOf(myItem.reactBundle) !== -1) {\n if (Lc[myItem.type]) {\n this.setState({ status: 'loading' })\n this.delayLoaded()\n } else {\n eventEmitter.on(myItem.type, function () {\n that.setState({ status: 'loading' })\n that.delayLoaded()\n })\n }\n return\n }\n myItem.reactBundle = myItem.reactBundle && myItem.reactBundle.replace('storage.jd.com', 'storage.360buyimg.com')\n downloadedBundles.push(myItem.reactBundle)\n var element = document.createElement('script')\n element.src = myItem.reactBundle\n element.charset = 'UTF-8'\n body.appendChild(element)\n element.onload = function () {\n that.setState({ status: 'loading' })\n that.delayLoaded()\n eventEmitter.trigger(myItem.type)\n }\n },\n componentDidMount: function () {\n this.updateOffsetTop()\n },\n componentWillReceiveProps: function (nextProps) {\n this.updateOffsetTop()\n },\n shouldComponentUpdate: function (nextProps, nextState) {\n return this.state.status !== nextState.status\n },\n componentDidCatch: function (error, info) {\n // console.log(error)\n // 上报组件渲染错误\n // @see //talos30011-prelb.o2athena.svc.n.jd.local/api-docs#null%2Fpaths%2F~1report%2Fpost\n var xhr = new XMLHttpRequest()\n xhr.open('POST', 'https://atom-log.3.cn/report', true)\n xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')\n xhr.send('platform=h5&url=' + location.href + '&cname=' + this.props.item.type + '&project=' + globalData.projectId)\n },\n getWrappedElement: function (extraProps) {\n if (this.WrappedElement) {\n return this.WrappedElement\n }\n var item = this.props.item\n var children = item.props.content || this.props.children || null\n var WrappedElement = genComponentElement(item.type, Object.assign({}, item.props, extraProps), children)\n this.WrappedElement = WrappedElement\n return WrappedElement\n },\n render: function () {\n var that = this\n var status = this.state.status\n // if (status === 'initial' || status === 'loading') {\n if (status === 'initial') {\n return Nerv.createElement(\n 'div',\n {\n style: {\n padding: '10px',\n backgroundClip: 'content-box',\n minHeight: '256px',\n height: '100%',\n backgroundColor: '#e3e4e5'\n }\n }\n // status === 'loading' ?\n // Nerv.createElement(\n // 'div',\n // {\n // style: {\n // width: 0,\n // height: 0,\n // overflow: 'hidden'\n // }\n // },\n // that.getWrappedElement()\n // ) : null\n )\n } else {\n // return that.getWrappedElement()\n // 缺点是多了一层 div\n this.cc = this.cc || that.getWrappedElement()\n return Nerv.createElement(\n 'div',\n status === 'loading' ? {\n style: {\n padding: '10px',\n backgroundClip: 'content-box',\n minHeight: '256px',\n height: '100%',\n backgroundColor: '#e3e4e5'\n }\n } : {},\n this.cc\n )\n }\n }\n })\n\n function createTree (tree) {\n tree = tree.filter(function (item) {\n return item.isShow === undefined || item.isShow === true\n })\n\n return tree.map(function (item) {\n var hasChildren = item.childrens && item.childrens.length\n hasChildren && (item.props.children = createTree(item.childrens))\n if (hasChildren) {\n return genComponentElement(item.type, item.props, item.props.content)\n } else {\n return Nerv.createElement(\n LingAtomScrollContext.Consumer,\n {},\n function (context) {\n return Nerv.createElement(\n LazyLoadComponent,\n {\n item: item,\n __context: context\n }\n )\n }\n )\n }\n })\n }\n\n var App = NervCreateClass({\n getInitialState: function () {\n return {\n scrollTop: 0,\n windowHeight: window.innerHeight,\n bodyHeight: document.body.clientHeight\n }\n },\n componentDidMount: function () {\n var that = this\n window.onscroll = throttle(function () {\n var bodyScrollHeight = document.documentElement.scrollTop || document.body.scrollTop\n that.setState({\n scrollTop: bodyScrollHeight\n })\n }, 200)\n window.onresize = function () {\n var windowInnerHeight = window.innerHeight\n if (windowInnerHeight === that.state.windowHeight) return\n that.setState({\n windowHeight: windowInnerHeight\n })\n }\n function onElementHeightChange (elm, callback) {\n var lastHeight = elm.clientHeight\n var newHeight\n (function run () {\n newHeight = elm.clientHeight\n if (lastHeight !== newHeight) {\n callback(newHeight)\n }\n lastHeight = newHeight\n if (elm.onElementHeightChangeTimer) {\n clearTimeout(elm.onElementHeightChangeTimer)\n }\n elm.onElementHeightChangeTimer = setTimeout(run, 200)\n })()\n }\n onElementHeightChange(document.body, function (h) {\n that.setState({ bodyHeight: h })\n })\n },\n render: function () {\n return Nerv.createElement(\n LingAtomScrollContext.Provider,\n {\n value: this.state\n },\n createTree(window.o2PageConfig.data)\n )\n }\n })\n\n Nerv.render(\n Nerv.createElement(App),\n document.querySelector('#app')\n )\n }()\n \n \n\n\n\n\n ✖ ✍操作台(点此拖动,左上角调整大小) \n ● 已选中1个元素,您可以:\n 确认采集 取消选择 Path: /html/body \n"}],"unique_index":"omeox2zzv8llhnebfs","iframe":false,"default":"","paraType":"text","recordASField":1,"beforeJS":"","beforeJSWaitTime":0,"JS":"","JSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"downloadPic":0}]}}]} \ No newline at end of file diff --git a/.temp_to_pub/EasySpider_windows_x64/info.log b/.temp_to_pub/EasySpider_windows_x64/info.log index 7bde5f1..9a4263e 100644 --- a/.temp_to_pub/EasySpider_windows_x64/info.log +++ b/.temp_to_pub/EasySpider_windows_x64/info.log @@ -223,3 +223,225 @@ cd ../ start EasySpider/resources/app/chrome_win64/easyspider_executestage.exe --id [26] --server_address http://localhost:8074 --user_data 0 ) else (start chrome_win64/easyspider_executestage.exe --id [26] --server_address http://localhost:8074 --user_data 0 ) ) +Server has started. +server_address: http://localhost:8074 +x64 +D:\Documents\Projects\EasySpider\.temp_to_pub\EasySpider_windows_x64\EasySpider\resources\app\chrome_win64\chromedriver_win64.exe D:\Documents\Projects\EasySpider\.temp_to_pub\EasySpider_windows_x64\EasySpider\resources\app\chrome_win64\chrome.exe D:\Documents\Projects\EasySpider\.temp_to_pub\EasySpider_windows_x64\EasySpider\resources\app\chrome_win64\execute.bat +win32 +Server listening on http://localhost:8075 +Not Windows 7 + + +GET A MESSAGE: { type: 0, message: { id: 2 } } +set socket_flowchart + + +GET A MESSAGE: { type: 0, message: { id: 0 } } +set socket_window + + +GET A MESSAGE: { type: 0, message: { id: 1 } } +set socket_start + + +GET A MESSAGE: { type: 0, message: { id: 'C99099946', title: 'Start' } } + + +GET A MESSAGE: { type: 0, message: { id: 1 } } +set socket_start + + +GET A MESSAGE: { type: 0, message: { id: 'C82841500', title: 'New Task' } } +Set handle_pair for id: C99099946 to C7971446D4E508FF193373A8C34CDEB7 , title is: Start +Set handle_pair for id: C82841500 to C7971446D4E508FF193373A8C34CDEB7 , title is: New Task + + +GET A MESSAGE: { + type: 3, + from: 0, + message: { + pipe: '{"type":"openPage","url":"https://www.jd.com","links":"https://www.jd.com"}' + } +} +FROM Browser: { + type: 'openPage', + url: 'https://www.jd.com', + links: 'https://www.jd.com' +} +Iframe: undefined + + +GET A MESSAGE: { type: 1, message: { id: -1 } } +Window { + id: 4654266, + processId: 57316, + path: 'D:\\Documents\\Projects\\EasySpider\\.temp_to_pub\\EasySpider_windows_x64\\EasySpider\\resources\\app\\chrome_win64\\chrome.exe' +} + + +GET A MESSAGE: { type: 0, message: { id: 'C33177600', title: '京东全球版-专业的综合网上购物商城' } } +Set handle_pair for id: C33177600 to C7971446D4E508FF193373A8C34CDEB7 , title is: 京东全球版-专业的综合网上购物商城 + + +GET A MESSAGE: { + type: 3, + from: 0, + message: { + pipe: '{"type":"loopClickEvery","id":"C33177600","history":4,"tabIndex":-1,"xpath":"/html/body/div[5]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div/a","allXPaths":"","useLoop":true,"iframe":false,"loopType":1}' + } +} +FROM Browser: { + type: 'loopClickEvery', + id: 'C33177600', + history: 4, + tabIndex: -1, + xpath: '/html/body/div[5]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div/a', + allXPaths: '', + useLoop: true, + iframe: false, + loopType: 1 +} +Iframe: false +handles [ 'C7971446D4E508FF193373A8C34CDEB7' ] +C33177600 C7971446D4E508FF193373A8C34CDEB7 +current_handle C7971446D4E508FF193373A8C34CDEB7 +switch to handle: C7971446D4E508FF193373A8C34CDEB7 + + +GET A MESSAGE: { type: 0, message: { id: 'C8210475', title: '手机通讯频道' } } +Set handle_pair for id: C8210475 to C7971446D4E508FF193373A8C34CDEB7 , title is: 手机通讯频道 + + +GET A MESSAGE: { + type: 3, + from: 0, + message: { + pipe: `{"type":"singleClick","id":"C8210475","history":5,"tabIndex":-1,"useLoop":false,"iframe":false,"xpath":"/html/body","allXPaths":["/html/body","//body[contains(., '')]","/html/body"]}` + } +} +FROM Browser: { + type: 'singleClick', + id: 'C8210475', + history: 5, + tabIndex: -1, + useLoop: false, + iframe: false, + xpath: '/html/body', + allXPaths: [ '/html/body', "//body[contains(., '')]", '/html/body' ] +} +Iframe: false +handles [ 'C7971446D4E508FF193373A8C34CDEB7' ] +C8210475 C7971446D4E508FF193373A8C34CDEB7 +current_handle C7971446D4E508FF193373A8C34CDEB7 +switch to handle: C7971446D4E508FF193373A8C34CDEB7 + + +GET A MESSAGE: { + type: 3, + from: 0, + message: { + pipe: `{"type":"singleCollect","history":5,"tabIndex":-1,"iframe":false,"parameters":[{"nodeType":0,"contentType":0,"relative":false,"name":"参数1_文本","desc":"","extractType":0,"relativeXPath":"/html/body","allXPaths":["/html/body","//body[contains(., '')]","/html/body"],"exampleValues":[{"num":0,"value":"\\n \\n \\n \\n \\n \\n 京东首页\\n \\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t海外 \\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t北京上海天津重庆河北山西河南辽宁吉林黑龙江内蒙古江苏山东安徽浙江福建湖北湖南广东广西江西四川海南贵州云南西藏陕西甘肃青海宁夏新疆港澳台湾钓鱼岛海外 \\t\\t\\t\\t \\t\\t\\t\\t \\t\\t\\t\\t \\t\\t\\t\\t 地区专享版本 \\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t中國港澳 \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t中國台灣 \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t京东全球 \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t \\t\\t\\t\\t \\t\\t\\t\\t \\t\\t\\t\\t \\t\\t\\t\\t Available Sites \\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\tGlobal Site \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\tСайт России \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\tSitus Indonesia \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\tSitio de España \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t\\t เว็บไซต์ประเทศไทย \\t\\t\\t\\t\\t\\t \\t\\t\\t\\t\\t \\t\\t\\t\\t \\t\\t\\t\\t \\t\\t\\t\\t\\t\\n \\n \\n 你好,请登录  免费注册\\n \\n \\n \\n 我的订单\\n \\n \\n \\n \\n \\n 我的京东\\n \\n \\n \\n \\n \\n \\n 京东会员\\n \\n \\n \\n \\n \\n 企业采购\\n \\n \\n \\n \\n \\n 客户服务\\n \\n \\n \\n \\n \\n \\n 网站导航\\n \\n \\n \\n \\n \\n \\n 手机京东\\n \\n \\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\t\\n 网站无障碍\\n \\n \\n \\n \\n \\n \\n\\n \\n \\n \\n (function (window) {\\n window.data = window.data || {}\\n window.data['cms_header'] = {\\n setting: [{\\"NAME\\":\\"手机\\",\\"URL\\":\\"//\\",\\"ANCHOR\\":\\"\\",\\"property\\":\\"\\",\\"CUSTOM1\\":\\"#050505\\",\\"CUSTOM2\\":\\"\\",\\"CUSTOM3\\":\\"\\"}]\\n }\\n })(window)\\n \\n \\n #search-2014 .text {border-color: #050505;}#search-2014 .button {background: #050505;} 京东 手机 全部分类◇ 搜索 >0 我的购物车 \\n \\n\\n \\n\\n \\n \\n 顶通组件占位手机分类热门推荐苹果华为荣耀小米vivoOPPO运营商手机卡营业厅充话费配件充电器数据线手机壳贴膜移动电源创意配件热门分类全部手机5G手机苹果 iPhone 11iPhone XS Max华为Mate40 Pro 4Gnova 8 Pro 无充Nova8SE 乐活版Mate 40 RSNova 9P50 Pro 4G华为智选手机荣耀荣耀V30 PRO荣耀30 Pro荣耀X10 Max荣耀Play4 Pro小米小米10Redmi K30vivoS10 ProX60Y70t iQOO 8 iQOO Neo5 iQOO Z3OPPOReno 6OPPO K9 Find X3品牌中国移动中国联通中国电信精选店铺京东通信北京移动广东移动宽带专区50M300M优选品牌Anker罗马仕品胜倍思绿联亿色毕亚兹斯泰克热卖爆款移动电源原装充电器散热背夹扩展坞苹果数据线氮化镓Type C信号放大器手游周边王者荣耀手机散热器吃鸡神器弯头线游戏手柄王座同屏器新奇好物氮化镓PD快充双向快充创意配件配件频道海量配件低至9.包邮机身存储16GB8GB4GB分辨率全高清FHD+高清HD+屏幕尺寸5.0英寸及以下5.0~5.49英寸5.5~5.99英寸6.0~6.24英寸有新机游戏手机手机营业厅手机好店以旧换新企业购热卖推荐人气新品限时特惠配件专区飞利浦(PHILIPS)真无线领夹麦克风小蜜蜂收音器直播vlog拍视频采访话筒设备手机通用DLM3540C¥199.00JBL音乐唱将KMC600无线麦克风蓝牙话筒音响一体麦克风全民/K歌 儿童K歌宝话筒家庭ktv玫瑰金¥599.00声阔Soundcore超能小彩蛋 LifeP3主动降噪真无线TWS入耳式蓝牙耳机适用苹果/华为/小米手机蓝30H续航版¥399.00漫步者(EDIFIER)W820NB经典版 头戴蓝牙主动降噪耳机 金标认证 手机电脑笔记本耳机 七夕情人节礼物 云岩白¥269.00\\n \\n \\n\\n \\n \\n \\n\\n \\n\\n \\n \\n window.pageConfig = window.pageConfig || {}\\n window.pageConfig.o2JSConfig = {\\n useTplInJs: true,\\n pathRule: function (path) {\\n return '//static.360buyimg.com/mtd/pc/cms' + '/floors/' + path + '.min.js'\\n }\\n }\\n \\n seajs.use(['//static.360buyimg.com/mtd/pc/base/1.0.1/channel.js'])\\n \\n seajs.use(['//wl.jd.com/wl.js'])\\n \\n \\n \\n !(function () {\\n var testObject = {}\\n if (!(Object.setPrototypeOf || testObject.__proto__)) {\\n var nativeGetPrototypeOf = Object.getPrototypeOf\\n Object.getPrototypeOf = function (object) {\\n return object.__proto__ || nativeGetPrototypeOf.call(Object, object)\\n }\\n }\\n })()\\n \\n \\n \\n \\n \\n \\n // nerv-create-class 用 'nervjs'\\n window.nervjs = Nerv\\n // nerv-create-class\\n !(function(t,e){\\"object\\"==typeof exports&&\\"undefined\\"!=typeof module?module.exports=e(require(\\"nervjs\\")):\\"function\\"==typeof define&&define.amd?define([\\"nervjs\\"],e):t.NervCreateClass=e(t.nervjs)})(this,(function(t){\\"use strict\\";function e(t){return t===undefined||null===t}function n(){}function r(t){return\\"function\\"==typeof t}function o(t){return t===undefined}function i(t,n){for(var r in n)e(n[r])||(t[r]=n[r]);return t}function a(t){for(var e in t){var n=t[e];\\"function\\"!=typeof n||n.__bound||1===g[e]||((t[e]=n.bind(t)).__bound=!0)}}function c(t,e){void 0===e&&(e={});for(var n=0,r=t.length;n wait) {\\n if (timeout) {\\n clearTimeout(timeout);\\n timeout = null;\\n }\\n previous = now;\\n func.apply(context, args);\\n } else if (!timeout) {\\n timeout = setTimeout(later, remaining);\\n }\\n };\\n return throttled;\\n }\\n // Context\\n var LingAtomScrollContext = Nerv.createContext({\\n scrollTop: 0,\\n windowHeight: 0,\\n bodyHeight: 0\\n })\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n function genComponentElement (type, props, children) {\\n \\n return Nerv.createElement(\\n Lc[type] ? Lc[type].component : 'div',\\n props,\\n children\\n )\\n \\n }\\n \\n \\n window.Lc = window.Lc || {}\\n Lc['Page'] = { component: 'div' }\\n \\n \\n function EventEmitter () {\\n var eventEmitterPool = {}\\n var eventEmitter = {\\n on: function (eventName, handler) {\\n eventEmitterPool[eventName] = eventEmitterPool[eventName] || []\\n eventEmitterPool[eventName].push(handler)\\n },\\n trigger: function (eventName) {\\n var handlers = eventEmitterPool[eventName] || []\\n var args = Array.prototype.slice.call(arguments, 1)\\n for (var i = 0; i < handlers.length; i++) {\\n handlers[i].apply(this, args)\\n }\\n },\\n off: function (eventName, handler) {\\n if (!eventEmitterPool[eventName]) return\\n if (!handler) {\\n eventEmitterPool[eventName] = []\\n return\\n }\\n var handlers = eventEmitterPool[eventName] || []\\n for (var i = 0; i < handlers.length; i++) {\\n `... 9044 more characters + } +} +FROM Browser: { + type: 'singleCollect', + history: 5, + tabIndex: -1, + iframe: false, + parameters: [ + { + nodeType: 0, + contentType: 0, + relative: false, + name: '参数1_文本', + desc: '', + extractType: 0, + relativeXPath: '/html/body', + allXPaths: [Array], + exampleValues: [Array], + unique_index: 'omeox2zzv8llhnebfs', + iframe: false + } + ] +} +Iframe: false + + +GET A MESSAGE: { type: 3, from: 1, message: { pipe: '{"type":0,"value":2}' } } +FROM Flowchart: { type: 0, value: 2 } + + +GET A MESSAGE: { type: 0, message: { id: 1 } } +set socket_start + + +GET A MESSAGE: { type: 0, message: { id: 1 } } +set socket_start + + +GET A MESSAGE: { + type: 5, + message: { + id: -1, + user_data_folder: '', + mysql_config_path: '-1', + execute_type: 1 + } +} +{ + id: -1, + user_data_folder: '', + mysql_config_path: '-1', + execute_type: 1 +} +0.json +1.json +10.json +11.json +12.json +13.json +14.json +15.json +16.json +17.json +18.json +19.json +2.json +20.json +21.json +22.json +23.json +24.json +25.json +26.json +27.json +3.json +4.json +5.json +6.json +7.json +8.json +9.json + + +GET A MESSAGE: { + type: 5, + message: { + id: 28, + user_data_folder: '', + mysql_config_path: './mysql_config.json', + execute_type: 1 + } +} +{ + id: 28, + user_data_folder: '', + mysql_config_path: './mysql_config.json', + execute_type: 1 +} + +D:\Documents\Projects\EasySpider\.temp_to_pub\EasySpider_windows_x64>if exist EasySpider (start EasySpider/resources/app/chrome_win64/easyspider_executestage.exe --id [28] --server_address http://localhost:8074 --user_data 0 ) else (if exist resources ( +cd ../ + start EasySpider/resources/app/chrome_win64/easyspider_executestage.exe --id [28] --server_address http://localhost:8074 --user_data 0 +) else (start chrome_win64/easyspider_executestage.exe --id [28] --server_address http://localhost:8074 --user_data 0 ) ) + diff --git a/.temp_to_pub/EasySpider_windows_x64/tasks/212.json b/.temp_to_pub/EasySpider_windows_x64/tasks/212.json new file mode 100644 index 0000000..f0610c5 --- /dev/null +++ b/.temp_to_pub/EasySpider_windows_x64/tasks/212.json @@ -0,0 +1 @@ +{"id":212,"name":"京东全球版-专业的综合网上购物商城","url":"https://www.jd.com","links":"https://www.jd.com","create_time":"8/19/2023, 2:38:26 PM","update_time":"8/19/2023, 2:38:26 PM","version":"0.5.0","saveThreshold":10,"cloudflare":0,"environment":0,"maxViewLength":15,"recordLog":1,"outputFormat":"xlsx","saveName":"current_time","inputExcel":"","startFromExit":0,"containJudge":false,"desc":"https://www.jd.com","inputParameters":[{"id":0,"name":"urlList_0","nodeId":1,"nodeName":"打开网页","value":"https://www.jd.com","desc":"要采集的网址列表,多行以\\n分开","type":"text","exampleValue":"https://www.jd.com"}],"outputParameters":[{"id":0,"name":"参数1_文本","desc":"","type":"text","recordASField":1,"exampleValue":"\n \n \n \n \n \n 京东首页\n \t\t\t\t\t\t\t\t\t\t\t海外 \t\t\t\t\t\t\t\t\t\t\t\t\t\t \t\t\t\t\t北京上海天津重庆河北山西河南辽宁吉林黑龙江内蒙古江苏山东安徽浙江福建湖北湖南广东广西江西四川海南贵州云南西藏陕西甘肃青海宁夏新疆港澳台湾钓鱼岛海外 \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t 地区专享版本 \t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t中國港澳 \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t中國台灣 \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t京东全球 \t\t\t\t\t \t\t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t Available Sites \t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tGlobal Site \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tСайт России \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tSitus Indonesia \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tSitio de España \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t เว็บไซต์ประเทศไทย \t\t\t\t\t\t \t\t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t\t\n \n \n 你好,请登录  免费注册\n \n \n \n 我的订单\n \n \n \n \n \n 我的京东\n \n \n \n \n \n \n 京东会员\n \n \n \n \n \n 企业采购\n \n \n \n \n \n 客户服务\n \n \n \n \n \n \n 网站导航\n \n \n \n \n \n \n 手机京东\n \n \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n 网站无障碍\n \n \n \n \n \n \n\n \n \n \n (function (window) {\n window.data = window.data || {}\n window.data['cms_header'] = {\n setting: [{\"NAME\":\"手机\",\"URL\":\"//\",\"ANCHOR\":\"\",\"property\":\"\",\"CUSTOM1\":\"#050505\",\"CUSTOM2\":\"\",\"CUSTOM3\":\"\"}]\n }\n })(window)\n \n \n #search-2014 .text {border-color: #050505;}#search-2014 .button {background: #050505;} 京东 手机 全部分类◇ 搜索 >0 我的购物车 \n \n\n \n\n \n \n 顶通组件占位手机分类热门推荐苹果华为荣耀小米vivoOPPO运营商手机卡营业厅充话费配件充电器数据线手机壳贴膜移动电源创意配件热门分类全部手机5G手机苹果 iPhone 11iPhone XS Max华为Mate40 Pro 4Gnova 8 Pro 无充Nova8SE 乐活版Mate 40 RSNova 9P50 Pro 4G华为智选手机荣耀荣耀V30 PRO荣耀30 Pro荣耀X10 Max荣耀Play4 Pro小米小米10Redmi K30vivoS10 ProX60Y70t iQOO 8 iQOO Neo5 iQOO Z3OPPOReno 6OPPO K9 Find X3品牌中国移动中国联通中国电信精选店铺京东通信北京移动广东移动宽带专区50M300M优选品牌Anker罗马仕品胜倍思绿联亿色毕亚兹斯泰克热卖爆款移动电源原装充电器散热背夹扩展坞苹果数据线氮化镓Type C信号放大器手游周边王者荣耀手机散热器吃鸡神器弯头线游戏手柄王座同屏器新奇好物氮化镓PD快充双向快充创意配件配件频道海量配件低至9.包邮机身存储16GB8GB4GB分辨率全高清FHD+高清HD+屏幕尺寸5.0英寸及以下5.0~5.49英寸5.5~5.99英寸6.0~6.24英寸有新机游戏手机手机营业厅手机好店以旧换新企业购热卖推荐人气新品限时特惠配件专区飞利浦(PHILIPS)真无线领夹麦克风小蜜蜂收音器直播vlog拍视频采访话筒设备手机通用DLM3540C¥199.00JBL音乐唱将KMC600无线麦克风蓝牙话筒音响一体麦克风全民/K歌 儿童K歌宝话筒家庭ktv玫瑰金¥599.00声阔Soundcore超能小彩蛋 LifeP3主动降噪真无线TWS入耳式蓝牙耳机适用苹果/华为/小米手机蓝30H续航版¥399.00漫步者(EDIFIER)W820NB经典版 头戴蓝牙主动降噪耳机 金标认证 手机电脑笔记本耳机 七夕情人节礼物 云岩白¥269.00\n \n \n\n \n \n \n\n \n\n \n \n window.pageConfig = window.pageConfig || {}\n window.pageConfig.o2JSConfig = {\n useTplInJs: true,\n pathRule: function (path) {\n return '//static.360buyimg.com/mtd/pc/cms' + '/floors/' + path + '.min.js'\n }\n }\n \n seajs.use(['//static.360buyimg.com/mtd/pc/base/1.0.1/channel.js'])\n \n seajs.use(['//wl.jd.com/wl.js'])\n \n \n \n !(function () {\n var testObject = {}\n if (!(Object.setPrototypeOf || testObject.__proto__)) {\n var nativeGetPrototypeOf = Object.getPrototypeOf\n Object.getPrototypeOf = function (object) {\n return object.__proto__ || nativeGetPrototypeOf.call(Object, object)\n }\n }\n })()\n \n \n \n \n \n \n // nerv-create-class 用 'nervjs'\n window.nervjs = Nerv\n // nerv-create-class\n !(function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e(require(\"nervjs\")):\"function\"==typeof define&&define.amd?define([\"nervjs\"],e):t.NervCreateClass=e(t.nervjs)})(this,(function(t){\"use strict\";function e(t){return t===undefined||null===t}function n(){}function r(t){return\"function\"==typeof t}function o(t){return t===undefined}function i(t,n){for(var r in n)e(n[r])||(t[r]=n[r]);return t}function a(t){for(var e in t){var n=t[e];\"function\"!=typeof n||n.__bound||1===g[e]||((t[e]=n.bind(t)).__bound=!0)}}function c(t,e){void 0===e&&(e={});for(var n=0,r=t.length;n wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n func.apply(context, args);\n } else if (!timeout) {\n timeout = setTimeout(later, remaining);\n }\n };\n return throttled;\n }\n // Context\n var LingAtomScrollContext = Nerv.createContext({\n scrollTop: 0,\n windowHeight: 0,\n bodyHeight: 0\n })\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n function genComponentElement (type, props, children) {\n \n return Nerv.createElement(\n Lc[type] ? Lc[type].component : 'div',\n props,\n children\n )\n \n }\n \n \n window.Lc = window.Lc || {}\n Lc['Page'] = { component: 'div' }\n \n \n function EventEmitter () {\n var eventEmitterPool = {}\n var eventEmitter = {\n on: function (eventName, handler) {\n eventEmitterPool[eventName] = eventEmitterPool[eventName] || []\n eventEmitterPool[eventName].push(handler)\n },\n trigger: function (eventName) {\n var handlers = eventEmitterPool[eventName] || []\n var args = Array.prototype.slice.call(arguments, 1)\n for (var i = 0; i < handlers.length; i++) {\n handlers[i].apply(this, args)\n }\n },\n off: function (eventName, handler) {\n if (!eventEmitterPool[eventName]) return\n if (!handler) {\n eventEmitterPool[eventName] = []\n return\n }\n var handlers = eventEmitterPool[eventName] || []\n for (var i = 0; i < handlers.length; i++) {\n if (handlers[i] === handler) {\n eventEmitterPool[eventName].splice(i, 1)\n break\n }\n }\n }\n }\n return eventEmitter\n }\n var eventEmitter = EventEmitter()\n\n !function () {\n var downloadedBundles = [\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a6__5ee34e5afc685b3ecdd0f087.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a7__5ee34e58fc685b3ecdd0f078.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a8__5ee34e5afc685b3ecdd0f08a.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a9__5fa90cbc7e292cb70199df98.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd594__5ee34e59fc685b3ecdd0f07e.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5aa__5ee34e5bfc685b3ecdd0f094.js\"]\n var body = document.body || document.documentElement\n var Wrap = function (props) {\n return props.children\n }\n // Lazyload Component\n var LazyLoadComponent = NervCreateClass({\n // loading loaded\n status: '',\n getInitialState: function () {\n return {\n status: 'initial'\n }\n },\n updateOffsetTop: function () {\n if (this.state.status !== 'initial') return\n var node = Nerv.findDOMNode(this)\n var rect = node.getBoundingClientRect()\n var winHeight = this.props.__context.windowHeight\n var canLoad = rect.top < winHeight * 1.5 && rect.top + rect.height > -winHeight * 0.5\n if (canLoad) {\n this.downloadScript()\n }\n },\n delayLoaded: function () {\n var that = this\n setTimeout(function () {\n that.setState({ status: 'loaded' })\n }, 500)\n },\n downloadScript: function () {\n var that = this\n var myItem = this.props.item\n if (!myItem.reactBundle || downloadedBundles.indexOf(myItem.reactBundle) !== -1) {\n if (Lc[myItem.type]) {\n this.setState({ status: 'loading' })\n this.delayLoaded()\n } else {\n eventEmitter.on(myItem.type, function () {\n that.setState({ status: 'loading' })\n that.delayLoaded()\n })\n }\n return\n }\n myItem.reactBundle = myItem.reactBundle && myItem.reactBundle.replace('storage.jd.com', 'storage.360buyimg.com')\n downloadedBundles.push(myItem.reactBundle)\n var element = document.createElement('script')\n element.src = myItem.reactBundle\n element.charset = 'UTF-8'\n body.appendChild(element)\n element.onload = function () {\n that.setState({ status: 'loading' })\n that.delayLoaded()\n eventEmitter.trigger(myItem.type)\n }\n },\n componentDidMount: function () {\n this.updateOffsetTop()\n },\n componentWillReceiveProps: function (nextProps) {\n this.updateOffsetTop()\n },\n shouldComponentUpdate: function (nextProps, nextState) {\n return this.state.status !== nextState.status\n },\n componentDidCatch: function (error, info) {\n // console.log(error)\n // 上报组件渲染错误\n // @see //talos30011-prelb.o2athena.svc.n.jd.local/api-docs#null%2Fpaths%2F~1report%2Fpost\n var xhr = new XMLHttpRequest()\n xhr.open('POST', 'https://atom-log.3.cn/report', true)\n xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')\n xhr.send('platform=h5&url=' + location.href + '&cname=' + this.props.item.type + '&project=' + globalData.projectId)\n },\n getWrappedElement: function (extraProps) {\n if (this.WrappedElement) {\n return this.WrappedElement\n }\n var item = this.props.item\n var children = item.props.content || this.props.children || null\n var WrappedElement = genComponentElement(item.type, Object.assign({}, item.props, extraProps), children)\n this.WrappedElement = WrappedElement\n return WrappedElement\n },\n render: function () {\n var that = this\n var status = this.state.status\n // if (status === 'initial' || status === 'loading') {\n if (status === 'initial') {\n return Nerv.createElement(\n 'div',\n {\n style: {\n padding: '10px',\n backgroundClip: 'content-box',\n minHeight: '256px',\n height: '100%',\n backgroundColor: '#e3e4e5'\n }\n }\n // status === 'loading' ?\n // Nerv.createElement(\n // 'div',\n // {\n // style: {\n // width: 0,\n // height: 0,\n // overflow: 'hidden'\n // }\n // },\n // that.getWrappedElement()\n // ) : null\n )\n } else {\n // return that.getWrappedElement()\n // 缺点是多了一层 div\n this.cc = this.cc || that.getWrappedElement()\n return Nerv.createElement(\n 'div',\n status === 'loading' ? {\n style: {\n padding: '10px',\n backgroundClip: 'content-box',\n minHeight: '256px',\n height: '100%',\n backgroundColor: '#e3e4e5'\n }\n } : {},\n this.cc\n )\n }\n }\n })\n\n function createTree (tree) {\n tree = tree.filter(function (item) {\n return item.isShow === undefined || item.isShow === true\n })\n\n return tree.map(function (item) {\n var hasChildren = item.childrens && item.childrens.length\n hasChildren && (item.props.children = createTree(item.childrens))\n if (hasChildren) {\n return genComponentElement(item.type, item.props, item.props.content)\n } else {\n return Nerv.createElement(\n LingAtomScrollContext.Consumer,\n {},\n function (context) {\n return Nerv.createElement(\n LazyLoadComponent,\n {\n item: item,\n __context: context\n }\n )\n }\n )\n }\n })\n }\n\n var App = NervCreateClass({\n getInitialState: function () {\n return {\n scrollTop: 0,\n windowHeight: window.innerHeight,\n bodyHeight: document.body.clientHeight\n }\n },\n componentDidMount: function () {\n var that = this\n window.onscroll = throttle(function () {\n var bodyScrollHeight = document.documentElement.scrollTop || document.body.scrollTop\n that.setState({\n scrollTop: bodyScrollHeight\n })\n }, 200)\n window.onresize = function () {\n var windowInnerHeight = window.innerHeight\n if (windowInnerHeight === that.state.windowHeight) return\n that.setState({\n windowHeight: windowInnerHeight\n })\n }\n function onElementHeightChange (elm, callback) {\n var lastHeight = elm.clientHeight\n var newHeight\n (function run () {\n newHeight = elm.clientHeight\n if (lastHeight !== newHeight) {\n callback(newHeight)\n }\n lastHeight = newHeight\n if (elm.onElementHeightChangeTimer) {\n clearTimeout(elm.onElementHeightChangeTimer)\n }\n elm.onElementHeightChangeTimer = setTimeout(run, 200)\n })()\n }\n onElementHeightChange(document.body, function (h) {\n that.setState({ bodyHeight: h })\n })\n },\n render: function () {\n return Nerv.createElement(\n LingAtomScrollContext.Provider,\n {\n value: this.state\n },\n createTree(window.o2PageConfig.data)\n )\n }\n })\n\n Nerv.render(\n Nerv.createElement(App),\n document.querySelector('#app')\n )\n }()\n \n \n\n\n\n\n ✖ ✍操作台(点此拖动,左上角调整大小) \n ● 已选中1个元素,您可以:\n 确认采集 取消选择 Path: /html/body \n"}],"graph":[{"index":0,"id":0,"parentId":0,"type":-1,"option":0,"title":"root","sequence":[1,2],"parameters":{"history":1,"tabIndex":0,"useLoop":false,"xpath":"","iframe":false,"wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0},"isInLoop":false},{"id":1,"index":1,"parentId":0,"type":0,"option":1,"title":"打开网页","sequence":[],"isInLoop":false,"position":0,"parameters":{"useLoop":false,"xpath":"","wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"url":"https://www.jd.com","links":"https://www.jd.com","maxWaitTime":10,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"cookies":""}},{"id":2,"index":2,"parentId":0,"type":1,"option":8,"title":"循环","sequence":[3,5],"isInLoop":false,"position":1,"parameters":{"history":4,"tabIndex":-1,"useLoop":false,"xpath":"/html/body/div[5]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div/a","iframe":false,"wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"loopType":1,"pathList":"","textList":"","code":"","waitTime":0,"exitCount":0,"historyWait":2,"breakMode":0,"breakCode":"","breakCodeWaitTime":0,"allXPaths":""}},{"id":3,"index":3,"parentId":2,"type":0,"option":2,"title":"点击元素","sequence":[],"isInLoop":true,"position":0,"parameters":{"history":4,"tabIndex":-1,"useLoop":true,"xpath":"","iframe":false,"wait":2,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"clickWay":0,"maxWaitTime":10,"paras":[],"allXPaths":"","loopType":1}},{"id":-1,"index":4,"parentId":2,"type":0,"option":2,"title":"点击元素","sequence":[],"isInLoop":true,"position":1,"parameters":{"history":5,"tabIndex":-1,"useLoop":false,"xpath":"/html/body","iframe":false,"wait":2,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"scrollType":0,"scrollCount":1,"scrollWaitTime":1,"clickWay":0,"maxWaitTime":10,"paras":[],"allXPaths":["/html/body","//body[contains(., '')]","/html/body"]}},{"id":4,"index":5,"parentId":2,"type":0,"option":3,"title":"提取数据","sequence":[],"isInLoop":true,"position":1,"parameters":{"history":5,"tabIndex":-1,"useLoop":false,"xpath":"","iframe":false,"wait":0,"waitType":0,"beforeJS":"","beforeJSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"waitElement":"","waitElementTime":10,"waitElementIframeIndex":0,"clear":0,"paras":[{"nodeType":0,"contentType":0,"relative":false,"name":"参数1_文本","desc":"","extractType":0,"relativeXPath":"/html/body","allXPaths":["/html/body","//body[contains(., '')]","/html/body"],"exampleValues":[{"num":0,"value":"\n \n \n \n \n \n 京东首页\n \t\t\t\t\t\t\t\t\t\t\t海外 \t\t\t\t\t\t\t\t\t\t\t\t\t\t \t\t\t\t\t北京上海天津重庆河北山西河南辽宁吉林黑龙江内蒙古江苏山东安徽浙江福建湖北湖南广东广西江西四川海南贵州云南西藏陕西甘肃青海宁夏新疆港澳台湾钓鱼岛海外 \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t 地区专享版本 \t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t中國港澳 \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t中國台灣 \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t京东全球 \t\t\t\t\t \t\t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t Available Sites \t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tGlobal Site \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tСайт России \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tSitus Indonesia \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\tSitio de España \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t \t\t\t\t\t\t เว็บไซต์ประเทศไทย \t\t\t\t\t\t \t\t\t\t\t \t\t\t\t \t\t\t\t \t\t\t\t\t\n \n \n 你好,请登录  免费注册\n \n \n \n 我的订单\n \n \n \n \n \n 我的京东\n \n \n \n \n \n \n 京东会员\n \n \n \n \n \n 企业采购\n \n \n \n \n \n 客户服务\n \n \n \n \n \n \n 网站导航\n \n \n \n \n \n \n 手机京东\n \n \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n 网站无障碍\n \n \n \n \n \n \n\n \n \n \n (function (window) {\n window.data = window.data || {}\n window.data['cms_header'] = {\n setting: [{\"NAME\":\"手机\",\"URL\":\"//\",\"ANCHOR\":\"\",\"property\":\"\",\"CUSTOM1\":\"#050505\",\"CUSTOM2\":\"\",\"CUSTOM3\":\"\"}]\n }\n })(window)\n \n \n #search-2014 .text {border-color: #050505;}#search-2014 .button {background: #050505;} 京东 手机 全部分类◇ 搜索 >0 我的购物车 \n \n\n \n\n \n \n 顶通组件占位手机分类热门推荐苹果华为荣耀小米vivoOPPO运营商手机卡营业厅充话费配件充电器数据线手机壳贴膜移动电源创意配件热门分类全部手机5G手机苹果 iPhone 11iPhone XS Max华为Mate40 Pro 4Gnova 8 Pro 无充Nova8SE 乐活版Mate 40 RSNova 9P50 Pro 4G华为智选手机荣耀荣耀V30 PRO荣耀30 Pro荣耀X10 Max荣耀Play4 Pro小米小米10Redmi K30vivoS10 ProX60Y70t iQOO 8 iQOO Neo5 iQOO Z3OPPOReno 6OPPO K9 Find X3品牌中国移动中国联通中国电信精选店铺京东通信北京移动广东移动宽带专区50M300M优选品牌Anker罗马仕品胜倍思绿联亿色毕亚兹斯泰克热卖爆款移动电源原装充电器散热背夹扩展坞苹果数据线氮化镓Type C信号放大器手游周边王者荣耀手机散热器吃鸡神器弯头线游戏手柄王座同屏器新奇好物氮化镓PD快充双向快充创意配件配件频道海量配件低至9.包邮机身存储16GB8GB4GB分辨率全高清FHD+高清HD+屏幕尺寸5.0英寸及以下5.0~5.49英寸5.5~5.99英寸6.0~6.24英寸有新机游戏手机手机营业厅手机好店以旧换新企业购热卖推荐人气新品限时特惠配件专区飞利浦(PHILIPS)真无线领夹麦克风小蜜蜂收音器直播vlog拍视频采访话筒设备手机通用DLM3540C¥199.00JBL音乐唱将KMC600无线麦克风蓝牙话筒音响一体麦克风全民/K歌 儿童K歌宝话筒家庭ktv玫瑰金¥599.00声阔Soundcore超能小彩蛋 LifeP3主动降噪真无线TWS入耳式蓝牙耳机适用苹果/华为/小米手机蓝30H续航版¥399.00漫步者(EDIFIER)W820NB经典版 头戴蓝牙主动降噪耳机 金标认证 手机电脑笔记本耳机 七夕情人节礼物 云岩白¥269.00\n \n \n\n \n \n \n\n \n\n \n \n window.pageConfig = window.pageConfig || {}\n window.pageConfig.o2JSConfig = {\n useTplInJs: true,\n pathRule: function (path) {\n return '//static.360buyimg.com/mtd/pc/cms' + '/floors/' + path + '.min.js'\n }\n }\n \n seajs.use(['//static.360buyimg.com/mtd/pc/base/1.0.1/channel.js'])\n \n seajs.use(['//wl.jd.com/wl.js'])\n \n \n \n !(function () {\n var testObject = {}\n if (!(Object.setPrototypeOf || testObject.__proto__)) {\n var nativeGetPrototypeOf = Object.getPrototypeOf\n Object.getPrototypeOf = function (object) {\n return object.__proto__ || nativeGetPrototypeOf.call(Object, object)\n }\n }\n })()\n \n \n \n \n \n \n // nerv-create-class 用 'nervjs'\n window.nervjs = Nerv\n // nerv-create-class\n !(function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e(require(\"nervjs\")):\"function\"==typeof define&&define.amd?define([\"nervjs\"],e):t.NervCreateClass=e(t.nervjs)})(this,(function(t){\"use strict\";function e(t){return t===undefined||null===t}function n(){}function r(t){return\"function\"==typeof t}function o(t){return t===undefined}function i(t,n){for(var r in n)e(n[r])||(t[r]=n[r]);return t}function a(t){for(var e in t){var n=t[e];\"function\"!=typeof n||n.__bound||1===g[e]||((t[e]=n.bind(t)).__bound=!0)}}function c(t,e){void 0===e&&(e={});for(var n=0,r=t.length;n wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n func.apply(context, args);\n } else if (!timeout) {\n timeout = setTimeout(later, remaining);\n }\n };\n return throttled;\n }\n // Context\n var LingAtomScrollContext = Nerv.createContext({\n scrollTop: 0,\n windowHeight: 0,\n bodyHeight: 0\n })\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n function genComponentElement (type, props, children) {\n \n return Nerv.createElement(\n Lc[type] ? Lc[type].component : 'div',\n props,\n children\n )\n \n }\n \n \n window.Lc = window.Lc || {}\n Lc['Page'] = { component: 'div' }\n \n \n function EventEmitter () {\n var eventEmitterPool = {}\n var eventEmitter = {\n on: function (eventName, handler) {\n eventEmitterPool[eventName] = eventEmitterPool[eventName] || []\n eventEmitterPool[eventName].push(handler)\n },\n trigger: function (eventName) {\n var handlers = eventEmitterPool[eventName] || []\n var args = Array.prototype.slice.call(arguments, 1)\n for (var i = 0; i < handlers.length; i++) {\n handlers[i].apply(this, args)\n }\n },\n off: function (eventName, handler) {\n if (!eventEmitterPool[eventName]) return\n if (!handler) {\n eventEmitterPool[eventName] = []\n return\n }\n var handlers = eventEmitterPool[eventName] || []\n for (var i = 0; i < handlers.length; i++) {\n if (handlers[i] === handler) {\n eventEmitterPool[eventName].splice(i, 1)\n break\n }\n }\n }\n }\n return eventEmitter\n }\n var eventEmitter = EventEmitter()\n\n !function () {\n var downloadedBundles = [\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a6__5ee34e5afc685b3ecdd0f087.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a7__5ee34e58fc685b3ecdd0f078.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a8__5ee34e5afc685b3ecdd0f08a.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5a9__5fa90cbc7e292cb70199df98.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd594__5ee34e59fc685b3ecdd0f07e.js\",\"//storage.360buyimg.com/quark-platform/component/standard/5cd436279a6ea5003becd5aa__5ee34e5bfc685b3ecdd0f094.js\"]\n var body = document.body || document.documentElement\n var Wrap = function (props) {\n return props.children\n }\n // Lazyload Component\n var LazyLoadComponent = NervCreateClass({\n // loading loaded\n status: '',\n getInitialState: function () {\n return {\n status: 'initial'\n }\n },\n updateOffsetTop: function () {\n if (this.state.status !== 'initial') return\n var node = Nerv.findDOMNode(this)\n var rect = node.getBoundingClientRect()\n var winHeight = this.props.__context.windowHeight\n var canLoad = rect.top < winHeight * 1.5 && rect.top + rect.height > -winHeight * 0.5\n if (canLoad) {\n this.downloadScript()\n }\n },\n delayLoaded: function () {\n var that = this\n setTimeout(function () {\n that.setState({ status: 'loaded' })\n }, 500)\n },\n downloadScript: function () {\n var that = this\n var myItem = this.props.item\n if (!myItem.reactBundle || downloadedBundles.indexOf(myItem.reactBundle) !== -1) {\n if (Lc[myItem.type]) {\n this.setState({ status: 'loading' })\n this.delayLoaded()\n } else {\n eventEmitter.on(myItem.type, function () {\n that.setState({ status: 'loading' })\n that.delayLoaded()\n })\n }\n return\n }\n myItem.reactBundle = myItem.reactBundle && myItem.reactBundle.replace('storage.jd.com', 'storage.360buyimg.com')\n downloadedBundles.push(myItem.reactBundle)\n var element = document.createElement('script')\n element.src = myItem.reactBundle\n element.charset = 'UTF-8'\n body.appendChild(element)\n element.onload = function () {\n that.setState({ status: 'loading' })\n that.delayLoaded()\n eventEmitter.trigger(myItem.type)\n }\n },\n componentDidMount: function () {\n this.updateOffsetTop()\n },\n componentWillReceiveProps: function (nextProps) {\n this.updateOffsetTop()\n },\n shouldComponentUpdate: function (nextProps, nextState) {\n return this.state.status !== nextState.status\n },\n componentDidCatch: function (error, info) {\n // console.log(error)\n // 上报组件渲染错误\n // @see //talos30011-prelb.o2athena.svc.n.jd.local/api-docs#null%2Fpaths%2F~1report%2Fpost\n var xhr = new XMLHttpRequest()\n xhr.open('POST', 'https://atom-log.3.cn/report', true)\n xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')\n xhr.send('platform=h5&url=' + location.href + '&cname=' + this.props.item.type + '&project=' + globalData.projectId)\n },\n getWrappedElement: function (extraProps) {\n if (this.WrappedElement) {\n return this.WrappedElement\n }\n var item = this.props.item\n var children = item.props.content || this.props.children || null\n var WrappedElement = genComponentElement(item.type, Object.assign({}, item.props, extraProps), children)\n this.WrappedElement = WrappedElement\n return WrappedElement\n },\n render: function () {\n var that = this\n var status = this.state.status\n // if (status === 'initial' || status === 'loading') {\n if (status === 'initial') {\n return Nerv.createElement(\n 'div',\n {\n style: {\n padding: '10px',\n backgroundClip: 'content-box',\n minHeight: '256px',\n height: '100%',\n backgroundColor: '#e3e4e5'\n }\n }\n // status === 'loading' ?\n // Nerv.createElement(\n // 'div',\n // {\n // style: {\n // width: 0,\n // height: 0,\n // overflow: 'hidden'\n // }\n // },\n // that.getWrappedElement()\n // ) : null\n )\n } else {\n // return that.getWrappedElement()\n // 缺点是多了一层 div\n this.cc = this.cc || that.getWrappedElement()\n return Nerv.createElement(\n 'div',\n status === 'loading' ? {\n style: {\n padding: '10px',\n backgroundClip: 'content-box',\n minHeight: '256px',\n height: '100%',\n backgroundColor: '#e3e4e5'\n }\n } : {},\n this.cc\n )\n }\n }\n })\n\n function createTree (tree) {\n tree = tree.filter(function (item) {\n return item.isShow === undefined || item.isShow === true\n })\n\n return tree.map(function (item) {\n var hasChildren = item.childrens && item.childrens.length\n hasChildren && (item.props.children = createTree(item.childrens))\n if (hasChildren) {\n return genComponentElement(item.type, item.props, item.props.content)\n } else {\n return Nerv.createElement(\n LingAtomScrollContext.Consumer,\n {},\n function (context) {\n return Nerv.createElement(\n LazyLoadComponent,\n {\n item: item,\n __context: context\n }\n )\n }\n )\n }\n })\n }\n\n var App = NervCreateClass({\n getInitialState: function () {\n return {\n scrollTop: 0,\n windowHeight: window.innerHeight,\n bodyHeight: document.body.clientHeight\n }\n },\n componentDidMount: function () {\n var that = this\n window.onscroll = throttle(function () {\n var bodyScrollHeight = document.documentElement.scrollTop || document.body.scrollTop\n that.setState({\n scrollTop: bodyScrollHeight\n })\n }, 200)\n window.onresize = function () {\n var windowInnerHeight = window.innerHeight\n if (windowInnerHeight === that.state.windowHeight) return\n that.setState({\n windowHeight: windowInnerHeight\n })\n }\n function onElementHeightChange (elm, callback) {\n var lastHeight = elm.clientHeight\n var newHeight\n (function run () {\n newHeight = elm.clientHeight\n if (lastHeight !== newHeight) {\n callback(newHeight)\n }\n lastHeight = newHeight\n if (elm.onElementHeightChangeTimer) {\n clearTimeout(elm.onElementHeightChangeTimer)\n }\n elm.onElementHeightChangeTimer = setTimeout(run, 200)\n })()\n }\n onElementHeightChange(document.body, function (h) {\n that.setState({ bodyHeight: h })\n })\n },\n render: function () {\n return Nerv.createElement(\n LingAtomScrollContext.Provider,\n {\n value: this.state\n },\n createTree(window.o2PageConfig.data)\n )\n }\n })\n\n Nerv.render(\n Nerv.createElement(App),\n document.querySelector('#app')\n )\n }()\n \n \n\n\n\n\n ✖ ✍操作台(点此拖动,左上角调整大小) \n ● 已选中1个元素,您可以:\n 确认采集 取消选择 Path: /html/body \n"}],"unique_index":"omeox2zzv8llhnebfs","iframe":false,"default":"","paraType":"text","recordASField":1,"beforeJS":"","beforeJSWaitTime":0,"JS":"","JSWaitTime":0,"afterJS":"","afterJSWaitTime":0,"downloadPic":0}]}}]} \ No newline at end of file diff --git a/ElectronJS/README.md b/ElectronJS/README.md index 14d9118..f3489e0 100644 --- a/ElectronJS/README.md +++ b/ElectronJS/README.md @@ -1,4 +1,4 @@ -# 环境编译说明/Environment Compilation Instruction +# 环境编译说明|Environment Compilation Instruction EasySpider分三部分: @@ -18,19 +18,32 @@ EasySpider is divided into three parts: This section covers the compilation instructions for the `main program`. -## 注意事项/Note + +## 建议编译顺序|Suggested Compilation Order + +1. 编译浏览器扩展,否则在主程序执行时会提示找不到`EasySpider_zh.crx`的错误。 +2. 编译主程序,此时主程序可以正常运行,但无法执行任务,只能设计任务。 +3. 编译执行阶段程序,否则无法执行程序,只能设计程序。 + +----- + +1. Compile the browser extension, otherwise an error will be prompted when the main program is executed that `EasySpider_en.crx` cannot be found. +2. Compile the main program, at this time the main program can run normally, but can not execute the task, can only design the task. +3. Compile the execution stage program, otherwise the program cannot be executed, can only design the program. + +## 注意事项|Note 请记住,每当EasySpider扩展程序和执行程序更新时,都要更新`EasySpider.crx`和`easyspider_executestage`文件。 Remember to update the `EasySpider.crx` and `easyspider_executestage` files whenever the EasySpider extension and execution program are updated. -## 环境构建/Environment Setup +## 环境构建|Environment Setup 以下以Windows x64版本为例。 Taking the example of Windows x64 version. -### 浏览器和驱动/Browser and Driver +### 浏览器和驱动|Browser and Driver 实在搞不定本节的情况下,下载一个直接能用的EasySpider,并把文件夹内的`EasySpider\resources\app\chrome_win64`文件夹拷贝到此`ElectronJS`文件夹下即可。 @@ -89,7 +102,7 @@ For example, if you want to build this software on Windows x64 platform, then yo Finally, copy the `stealth.min.js` and `execute.bat` (for Windows x64) file in this folder to these `chrome` folders. -### NodeJS环境/NodeJS Environment +### NodeJS环境|NodeJS Environment 1. Windows环境下需要先安装`VS Build Tools 2017` ([https://aka.ms/vs/15/release/vs_buildtools.exe](https://aka.ms/vs/15/release/vs_buildtools.exe))的`Visual C++ Build Tools`组件,不然下面的命令无法执行,其他系统不需要。 2. 安装`NodeJS`:[https://nodejs.org/zh-cn/download/](https://nodejs.org/zh-cn/download/)。 @@ -113,7 +126,7 @@ npm install npm install @electron-forge/cli -g ``` -## 运行说明/Run Instruction +## 运行说明|Run Instruction 在当前文件夹执行以下命令即可在开发模式下运行程序: @@ -133,7 +146,7 @@ npm run start_direct But so far can only design the task, can not execute the task, want to execute the task also need to complete the 'ExecuteStage' folder of the execution of the task program compilation instructions can be executed. -## 打包发布说明/Package Instruction +## 打包发布说明|Package Instruction 打包发布前,确保执行阶段程序`easyspider_executestage(.exe)`已放入`chrome(_win64)`文件夹内,且浏览器插件`EasySpider_zh.crx`已经是最新版本。 @@ -173,7 +186,7 @@ package_win64.cmd clean_and_release_win64.cmd ``` -### (可选)编译成安装包/(Optional) Compile to an installation package +### (可选)编译成安装包|(Optional) Compile to an installation package ``` npm run make diff --git a/ElectronJS/execute_win32.bat b/ElectronJS/execute_win32.bat new file mode 100644 index 0000000..d589806 --- /dev/null +++ b/ElectronJS/execute_win32.bat @@ -0,0 +1,11 @@ +@REM msg * %cd% +if exist EasySpider ( + start EasySpider/resources/app/chrome_win32/easyspider_executestage.exe %1 %2 %3 %4 %5 %6 %7 %8 %9 +) else ( +if exist resources ( + cd ../ + start EasySpider/resources/app/chrome_win32/easyspider_executestage.exe %1 %2 %3 %4 %5 %6 %7 %8 %9 + ) else ( + start chrome_win64/easyspider_executestage.exe %1 %2 %3 %4 %5 %6 %7 %8 %9 + ) +) diff --git a/ElectronJS/execute.bat b/ElectronJS/execute_win64.bat similarity index 100% rename from ElectronJS/execute.bat rename to ElectronJS/execute_win64.bat diff --git a/ElectronJS/update_chrome.py b/ElectronJS/update_chrome.py index 96213dd..cac4ec8 100644 --- a/ElectronJS/update_chrome.py +++ b/ElectronJS/update_chrome.py @@ -150,7 +150,7 @@ if __name__ == "__main__": for folder in os.listdir("./chrome_win64"): if folder[0].isdigit() and os.path.isdir("./chrome_win64/"+folder): shutil.rmtree("./chrome_win64/"+folder+"/Installer") # 删除Installer文件夹 - copy_file("./execute.bat", "./chrome_win64/execute.bat") + copy_file("./execute_win64.bat", "./chrome_win64/execute.bat") copy_file("./stealth.min.js", "./chrome_win64/stealth.min.js") try: copy_file( @@ -177,7 +177,7 @@ if __name__ == "__main__": for folder in os.listdir("./chrome_win32"): if folder[0].isdigit() and os.path.isdir("./chrome_win32/"+folder): shutil.rmtree("./chrome_win32/"+folder+"/Installer") # 删除Installer文件夹 - copy_file("./execute.bat", "./chrome_win32/execute.bat") + copy_file("./execute_win32.bat", "./chrome_win32/execute.bat") copy_file("./stealth.min.js", "./chrome_win32/stealth.min.js") try: copy_file( diff --git a/ExecuteStage/Readme.md b/ExecuteStage/Readme.md index 7d66c2d..ff637c9 100644 --- a/ExecuteStage/Readme.md +++ b/ExecuteStage/Readme.md @@ -1,4 +1,4 @@ -# 环境编译说明/Environment Compilation Instruction +# 环境编译说明|Environment Compilation Instruction EasySpider分三部分: @@ -18,7 +18,20 @@ EasySpider is divided into three parts: This section covers the compilation instructions for the `Execution stage program`. -## 环境构建/Environment Setup +## 建议编译顺序|Suggested Compilation Order + +1. 编译浏览器扩展,否则在主程序执行时会提示找不到`EasySpider_zh.crx`的错误。 +2. 编译主程序,此时主程序可以正常运行,但无法执行任务,只能设计任务。 +3. 编译执行阶段程序,否则无法执行程序,只能设计程序。 + +----- + +1. Compile the browser extension, otherwise an error will be prompted when the main program is executed that `EasySpider_en.crx` cannot be found. +2. Compile the main program, at this time the main program can run normally, but can not execute the task, can only design the task. +3. Compile the execution stage program, otherwise the program cannot be executed, can only design the program. + + +## 环境构建|Environment Setup 1. 安装Python 3.7及以上版本并添加至系统环境变量:[https://www.python.org/downloads/](https://www.python.org/downloads/)。 2. 安装`pip3`并添加至系统环境变量(Windows安装python后会自带pip,Linux和MacOS安装方式请自行搜索)。 @@ -38,7 +51,7 @@ This section covers the compilation instructions for the `Execution stage progra pip3 install -r requirements.txt ``` -## 运行说明/Run Instruction +## 运行说明|Run Instruction 运行程序前,确保已经完成了`ElectronJS`文件夹下`主程序`的编译,保证`chrome`文件夹和`chromedriver`环境已经就绪,同时**EasySpider主程序已在运行中**。 @@ -62,13 +75,13 @@ python3 easyspider_executestage.py --id [1] The above is an example command to run a task with the ID of `1`. For more information on command-line parameters, please refer to: [Argument Instruction](https://github.com/NaiboWang/EasySpider/wiki/Argument-Instruction) on the project's GitHub Wiki. -### VS Code调试/VS Code Debug +### VS Code调试|VS Code Debug 可以用VS Code打开此文件夹即可调试程序,可修改`.vscode`下的`launch.json`文件中的调试参数,调试说明参考:[https://zhuanlan.zhihu.com/p/41189402](https://zhuanlan.zhihu.com/p/41189402)。 You can use VS Code to open this folder and debug the program. You can modify the debugging parameters in the launch.json file located under the .vscode folder. For instructions on debugging with VSCode, you can refer to this guide: [Debugging Python with Visual Studio Code](https://code.visualstudio.com/docs/python/debugging). -## 打包说明/Package Instruction +## 打包说明|Package Instruction 如果想要在主程序直接点击`本地直接运行`按钮即可执行程序,则需要打包程序为可执行程序。 diff --git a/Extension/README.md b/Extension/README.md index a40d649..890cd61 100644 --- a/Extension/README.md +++ b/Extension/README.md @@ -1,4 +1,4 @@ -# 环境编译说明/Environment Compilation Instruction +# 环境编译说明|Environment Compilation Instruction EasySpider分三部分: @@ -18,7 +18,20 @@ EasySpider is divided into three parts: This section covers the compilation instructions for the `Browser extension`, **all commands in this section are executed in the `manifest_v3` folder**, i.e., you need to `cd manifest_v3` first. -## 环境构建/Environment Setup +## 建议编译顺序|Suggested Compilation Order + +1. 编译浏览器扩展,否则在主程序执行时会提示找不到`EasySpider_zh.crx`的错误。 +2. 编译主程序,此时主程序可以正常运行,但无法执行任务,只能设计任务。 +3. 编译执行阶段程序,否则无法执行程序,只能设计程序。 + +----- + +1. Compile the browser extension, otherwise an error will be prompted when the main program is executed that `EasySpider_en.crx` cannot be found. +2. Compile the main program, at this time the main program can run normally, but can not execute the task, can only design the task. +3. Compile the execution stage program, otherwise the program cannot be executed, can only design the program. + + +## 环境构建|Environment Setup 1. 安装`NodeJS`:[https://nodejs.org/zh-cn/download/](https://nodejs.org/zh-cn/download/)。 2. 运行下面的命令来安装依赖: @@ -36,7 +49,7 @@ npm install npm install ``` -## 热加载扩展/Hot reload the extension +## 热加载扩展|Hot reload the extension 执行下面的命令来热加载扩展: @@ -56,7 +69,7 @@ npm run dev Open a Chrome browser window, then enter `chrome://extensions/` in the browser address bar. On the opened page, open the `Developer mode` in the upper right corner, click `Load unpacked` and select the `manifest_v3/dist` folder to load the extension. -## 打包扩展/Package the extension +## 打包扩展|Package the extension 执行下面的命令来打包扩展: