From 05ba4a7fcedf5866fd8888e1046e9f0929d7b55f Mon Sep 17 00:00:00 2001 From: KonghaYao <20192831006@m.scnu.edu.cn> Date: Tue, 20 Jul 2021 20:06:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(plugins):=20fix=20plugins=20=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E5=AF=BC=E5=85=A5=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DEMO.js | 28 ---------------------------- README.md | 30 ++++++++++-------------------- VERSION.md | 3 +-- dist/JSpider.esm.min.js | 37 +++++++++++++++++++++++++------------ dist/JSpider.min.js | 37 +++++++++++++++++++++++++------------ plugins/Download.js | 2 +- plugins/ExcelHelper.js | 2 +- plugins/ExcelHelper/xlsx.js | 2 +- plugins/JSzip/JSzip.js | 2 +- plugins/Request.js | 4 ++-- plugins/zipFile.js | 4 ++-- test/Request.js | 2 +- 12 files changed, 70 insertions(+), 83 deletions(-) delete mode 100644 DEMO.js diff --git a/DEMO.js b/DEMO.js deleted file mode 100644 index 0b2165d..0000000 --- a/DEMO.js +++ /dev/null @@ -1,28 +0,0 @@ -// JSpider 是一个完整的类,支持链式调用 - -// 申明一些 JSpider 实例的 config -const spider = new JSpider(); -JSpider.Memory({ - connect: 'indexedDB', // 选择存储的位置 - storageName: 'default', // 存储区域的名称 -}); -// 定义处理数据的方法 -spider.pipeline( - Request(), - ExcelHelper(function preprocess(data) { - return data; - }), - Plugin((data) => { - console.log(data); - return data; - }), - // Download() -); - -// 爬虫启动 -spider.crawl(string); -spider.crawl([string, string]); -spider.crawl(string1, string2); - -// 模拟中断爬虫 -const paused = new Promise((resolve) => setTimeout(() => spider.stop().then(() => resolve()), 5000)); diff --git a/README.md b/README.md index e34b4ba..599e63e 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,22 @@ -# JSpider 3 BETA +# JSpider 3.2 BETA -[![](https://data.jsdelivr.com/v1/package/npm/js-spider/badge)](https://www.jsdelivr.com/package/npm/js-spider) ![npm](https://img.shields.io/npm/v/js-spider?style=flat-square) ![NPM](https://img.shields.io/npm/l/js-spider?style=flat-square) ![GitHub top language](https://img.shields.io/github/languages/top/konghayao/jspider) ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/konghayao/jspider) ![Website](https://img.shields.io/website?style=flat-square&up_color=green&up_message=online&url=http%3A%2F%2Fdongzhongzhidong.gitee.io%2Fjspider%2F) [![](https://gitee.com/dongzhongzhidong/jspider/badge/star.svg?theme=white)](https://gitee.com/dongzhongzhidong/jspider/) +[![](https://data.jsdelivr.com/v1/package/npm/js-spider/badge)](https://www.jsdelivr.com/package/npm/js-spider) ![npm](https://img.shields.io/npm/v/js-spider?style=flat-square) ![NPM](https://img.shields.io/npm/l/js-spider?style=flat-square) ![GitHub top language](https://img.shields.io/github/languages/top/konghayao/jspider) ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/konghayao/jspider) [![](https://gitee.com/dongzhongzhidong/jspider/badge/star.svg?theme=white)](https://gitee.com/dongzhongzhidong/jspider/) > JSpider 3 是在 Chrome Devtools 中进行爬虫的爬虫框架,这个框架包括了完整的爬虫支持。如果您具有前端基础,那么可以在三分钟内入门哦! -[官方教程链接](http://dongzhongzhidong.gitee.io/jspider/) - -## 快速入门 +> JSpider 3 is a Chrome DevTools crawler framework that includes full crawler support. If you have a front-end foundation, you can get up and running in three minutes! -### 极速爬取 +- **高效率工具:JSpider 自带并发控制,提供多种方便的数据处理插件。** +- **爬虫高度复用:JSpider 的代码可以重复使用,随时添加新任务。** -只有简单的几行,适用于极速操作,这会直接将这些 URL 中的内容下载到本地。 - -> 右键 -> 检查,打开浏览器 Devtools,在 Console 中即可使用这些代码哦! +[官方教程链接](http://dongzhongzhidong.gitee.io/jspider/) -```js -import('https://cdn.jsdelivr.net/npm/js-spider/dist/JSpider.esm.min.js').then({JSpider}=>{ - window.JSpider = JSpider; -});// 从 jsDelivr 导入代码 -// 放入您的 URL -JSpider.simpleCrawl(["fake/excel","fake/excel"]); -// 等待文件下载完成! -``` +## 快速入门 -### 更加高级的自定义爬取 +### 自定义爬取 ```js -import('https://cdn.jsdelivr.net/npm/js-spider/dist/JSpider.esm.min.js').then({JSpider}=>{ +await import('https://cdn.jsdelivr.net/npm/js-spider/dist/JSpider.esm.min.js').then({JSpider}=>{ window.JSpider = JSpider; }); @@ -36,7 +26,7 @@ const { Download, // 下载库 } = JSpider.plugins; -let urls = ['']// 您的爬取路径数组 +let urls = ['https://.....']// 您的爬取路径数组 const spider = new JSpider( Request(), diff --git a/VERSION.md b/VERSION.md index 6f8c0c4..a960ecd 100644 --- a/VERSION.md +++ b/VERSION.md @@ -18,12 +18,11 @@ - 重构所有的核心代码 - - [ ] Control Panel 暂停功能 + - [x] Control Panel 暂停功能 - [ ] Control Panel 重试功能(非流内自动重试) - 重构 plugins - [ ] plugins 分包导入 - - [ ] Request 多平台 > 因为是 3.2 版本才更新这个文件,所以以前的版本都丢失了。 diff --git a/dist/JSpider.esm.min.js b/dist/JSpider.esm.min.js index 1cf98eb..6227dcb 100644 --- a/dist/JSpider.esm.min.js +++ b/dist/JSpider.esm.min.js @@ -3718,13 +3718,17 @@ var pick = flatRest(function(object, paths) { * SPDX-License-Identifier: Apache-2.0 */ +/** + * EventHub 是一个事件处理中心,用于事件的接收与派发 + */ + class EventHub { all = new Map(); constructor(eventMap = {}, bindThis = null) { this.bindThis = bindThis || globalThis; this.on(eventMap); - // 创建一个 rxjs 流源头 + // createSource$ 创建一个 rxjs 流的源头监听相应的事件 this.createSource$ = memoize((eventName) => { return fromEventPattern( (handle) => this.on(eventName, handle), @@ -3732,12 +3736,23 @@ class EventHub { ); }); } + + /** + * #on 是单个事件绑定函数,type 与 handle 函数一一对应 + */ #on(type, handler) { const handlers = this.all.get(type); // ! 注意,栈的结构,这里要使用 unshift 将元素插入到头部,这样触发的时候才会最后执行最先声明的函数作为默认函数 // 栈的结构可以保证 在 destroy 事件的时候,首先定义的 destroy 可以最后执行,保证后面绑定 destroy 事件的函数可以先触发,而在 destroy 的定义函数中可以最后 off('*') 解除事件 handlers ? handlers.unshift(handler) : this.all.set(type, [handler]); } + + /** + * on 函数重载,第一个参数可以为一个事件绑定对象, + * on({eventName: callback }) + * on({eventName: [callback] }) + * on(type,handle) + */ on(type, handler) { // 函数重载 if (typeof type === 'string') { @@ -3747,12 +3762,16 @@ class EventHub { Object.entries(type).forEach(([key, value]) => { if (value instanceof Array) { value.forEach((item) => this.#on(key, item)); - } else { + } else if (value instanceof Function) { this.#on(key, value); } }); } } + + /** + * off 函数 type 设置为 '*' 时删除所有函数 + */ off(type, handler) { if (type === '*') { return this.all.clear(); @@ -3773,11 +3792,6 @@ class EventHub { }) : []; } - - operators = { - // TODO EventHub 中对于 rxjs 流的支持 - EmitWhen(config) {}, - }; } /** @@ -4067,14 +4081,13 @@ function createUUID(string) { * Copyright 2021 KonghaYao 江夏尧 * SPDX-License-Identifier: Apache-2.0 */ + /** * 函数用途描述 - * 这个是用于 async 函数队列 连续执行的函数,只要 enQueue 之后就会连续执行,直至停止 + * 这个是用于 async 函数队列 连续执行的函数,只要 enQueue 之后就会连续执行,直至完成 */ - class functionQueue { QueuePromise = Promise.resolve(); - constructor() {} enQueue(...args) { this.QueuePromise = args.reduce((promise, current) => { return promise.then(current); @@ -4479,7 +4492,7 @@ class ControlPanel$1 { startFlow() { this.$EventHub.emit('Flow:start'); } - // TODO 测试暂停功能 + stopFlow() { this.$EventHub.emit('Flow:stop'); } @@ -6256,7 +6269,7 @@ var index = Object.assign(Spider, tools, { Task, TaskGroup, version: "3.1.8", - buildDate: new Date(1626743574108), + buildDate: new Date(1626782541521), }); export default index; diff --git a/dist/JSpider.min.js b/dist/JSpider.min.js index 4e43c95..f1c7ab0 100644 --- a/dist/JSpider.min.js +++ b/dist/JSpider.min.js @@ -3721,13 +3721,17 @@ var JSpider = (function () { * SPDX-License-Identifier: Apache-2.0 */ + /** + * EventHub 是一个事件处理中心,用于事件的接收与派发 + */ + class EventHub { all = new Map(); constructor(eventMap = {}, bindThis = null) { this.bindThis = bindThis || globalThis; this.on(eventMap); - // 创建一个 rxjs 流源头 + // createSource$ 创建一个 rxjs 流的源头监听相应的事件 this.createSource$ = memoize((eventName) => { return fromEventPattern( (handle) => this.on(eventName, handle), @@ -3735,12 +3739,23 @@ var JSpider = (function () { ); }); } + + /** + * #on 是单个事件绑定函数,type 与 handle 函数一一对应 + */ #on(type, handler) { const handlers = this.all.get(type); // ! 注意,栈的结构,这里要使用 unshift 将元素插入到头部,这样触发的时候才会最后执行最先声明的函数作为默认函数 // 栈的结构可以保证 在 destroy 事件的时候,首先定义的 destroy 可以最后执行,保证后面绑定 destroy 事件的函数可以先触发,而在 destroy 的定义函数中可以最后 off('*') 解除事件 handlers ? handlers.unshift(handler) : this.all.set(type, [handler]); } + + /** + * on 函数重载,第一个参数可以为一个事件绑定对象, + * on({eventName: callback }) + * on({eventName: [callback] }) + * on(type,handle) + */ on(type, handler) { // 函数重载 if (typeof type === 'string') { @@ -3750,12 +3765,16 @@ var JSpider = (function () { Object.entries(type).forEach(([key, value]) => { if (value instanceof Array) { value.forEach((item) => this.#on(key, item)); - } else { + } else if (value instanceof Function) { this.#on(key, value); } }); } } + + /** + * off 函数 type 设置为 '*' 时删除所有函数 + */ off(type, handler) { if (type === '*') { return this.all.clear(); @@ -3776,11 +3795,6 @@ var JSpider = (function () { }) : []; } - - operators = { - // TODO EventHub 中对于 rxjs 流的支持 - EmitWhen(config) {}, - }; } /** @@ -4070,14 +4084,13 @@ var JSpider = (function () { * Copyright 2021 KonghaYao 江夏尧 * SPDX-License-Identifier: Apache-2.0 */ + /** * 函数用途描述 - * 这个是用于 async 函数队列 连续执行的函数,只要 enQueue 之后就会连续执行,直至停止 + * 这个是用于 async 函数队列 连续执行的函数,只要 enQueue 之后就会连续执行,直至完成 */ - class functionQueue { QueuePromise = Promise.resolve(); - constructor() {} enQueue(...args) { this.QueuePromise = args.reduce((promise, current) => { return promise.then(current); @@ -4482,7 +4495,7 @@ var JSpider = (function () { startFlow() { this.$EventHub.emit('Flow:start'); } - // TODO 测试暂停功能 + stopFlow() { this.$EventHub.emit('Flow:stop'); } @@ -6259,7 +6272,7 @@ var JSpider = (function () { Task, TaskGroup, version: "3.1.8", - buildDate: new Date(1626743574108), + buildDate: new Date(1626782541521), }); return index; diff --git a/plugins/Download.js b/plugins/Download.js index 0db0343..fd153be 100644 --- a/plugins/Download.js +++ b/plugins/Download.js @@ -5,7 +5,7 @@ */ import { toFile } from './utils/toFile.js'; -import { Plugin } from '../Pipeline/PluginSystem.js'; +import { Plugin } from '../src/Pipeline/PluginSystem.js'; // 在 浏览器中下载是不能够同时进行的,也就是说,如果前面的没有下载完,后面的又提交 // 会导致后面的全部失效,所以设置 Promise 下载队列 const DownloadQueue = { diff --git a/plugins/ExcelHelper.js b/plugins/ExcelHelper.js index 90f3cd3..91a7ee0 100644 --- a/plugins/ExcelHelper.js +++ b/plugins/ExcelHelper.js @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ import { createExcelFile } from './ExcelHelper/createExcelFile.js'; -import { Plugin } from '../Pipeline/PluginSystem.js'; +import { Plugin } from '../src/Pipeline/PluginSystem.js'; import { init } from './ExcelHelper/xlsx.js'; // 未完成 导入 XLSX 的 Promise 到流的转变 diff --git a/plugins/ExcelHelper/xlsx.js b/plugins/ExcelHelper/xlsx.js index 521e79a..b2a6f38 100644 --- a/plugins/ExcelHelper/xlsx.js +++ b/plugins/ExcelHelper/xlsx.js @@ -3,7 +3,7 @@ * Copyright 2021 KonghaYao 江夏尧 * SPDX-License-Identifier: Apache-2.0 */ -import { $load } from '../../tools/loader/loader.js'; +import { $load } from '../../src/tools/loader/loader.js'; let XLSX; function init() { diff --git a/plugins/JSzip/JSzip.js b/plugins/JSzip/JSzip.js index 9282ad3..923f8d0 100644 --- a/plugins/JSzip/JSzip.js +++ b/plugins/JSzip/JSzip.js @@ -3,7 +3,7 @@ * Copyright 2021 KonghaYao 江夏尧 * SPDX-License-Identifier: Apache-2.0 */ -import { $load } from '../../tools/loader/loader.js'; +import { $load } from '../../src/tools/loader/loader.js'; let JSZip; function init() { diff --git a/plugins/Request.js b/plugins/Request.js index b9c270d..241790f 100644 --- a/plugins/Request.js +++ b/plugins/Request.js @@ -5,8 +5,8 @@ */ /* eslint-disable no-invalid-this */ -import { Plugin } from '../Pipeline/PluginSystem.js'; -import { concurrent } from '../utils/concurrent.js'; +import { Plugin } from '../src/Pipeline/PluginSystem.js'; +import { concurrent } from '../src/utils/concurrent.js'; // ! 这个 Request 文件是标准的 Plugin 的高级注册示例 diff --git a/plugins/zipFile.js b/plugins/zipFile.js index ecef75c..ed16d5f 100644 --- a/plugins/zipFile.js +++ b/plugins/zipFile.js @@ -5,13 +5,13 @@ */ import { bufferTime, concatMap, filter } from 'rxjs/operators'; -import { Plugin } from '../Pipeline/PluginSystem.js'; +import { Plugin } from '../src/Pipeline/PluginSystem.js'; import { init } from './JSzip/JSzip.js'; import { zipper } from './JSzip/zipper.js'; import { toFile } from './utils/toFile.js'; -import { TaskGroup } from '../TaskSystem/TaskGroup.js'; +import { TaskGroup } from '../src/TaskSystem/TaskGroup.js'; export const ZipFile = function (options = {}) { if (!options.zipFileName) options.zipFileName = new Date().getTime(); diff --git a/test/Request.js b/test/Request.js index 0afe0e1..59fe2e9 100644 --- a/test/Request.js +++ b/test/Request.js @@ -33,5 +33,5 @@ export async function main() { // Download(), ); spider.crawl(urls); - window.spider = spider; + spider.start(); }