文章定时自动采集(这样的一个小报系统是如何实现的呢?(组图))
优采云 发布时间: 2022-01-19 01:07文章定时自动采集(这样的一个小报系统是如何实现的呢?(组图))
下图是政采云前端小报( )官网截图,里面收录了我们每一期历史的总结~
截止目前,前端小报93期,汇聚1000+文章,涵盖50+大小品类。可以说是很不错的知识库了~
前端小报的由来
持续学习是每个工程师都必须的,一个成长中的团队也需要这样的持续学习氛围。那么如何利用技术帮助团队培养持续学习的氛围呢?
于是,正财云前端小报应运而生。主要包括提交、聚合沉淀、定时投递三个核心模块。这样的系统可以让大家轻松将自己喜欢的文章分享给团队,对分享文章进行分类沉淀,为团队打造知识库,方便大家查阅。同时,小报系统每周五也会定时推送,让大家了解最新的科技动态。分享学习氛围的好帮手~
那么这样一个小报系统是如何运作的呢?
如何为提交设计一个小报系统
我相信当你看到一个好的文章时,总会有一种与他人分享的冲动。一个简单易用的推送功能,可以轻松满足大家的分享欲望。好文章进队帮助其他同学~
一个简单易行的贡献函数,我们需要解决两个问题:
1、看到好东西如何满足分享的冲动文章
2、提交的文章如何分类采集,方便沉淀和搜索
如果是单独录入系统和人工录入,这种方式操作起来比较麻烦,而且很容易打消大家的积极性。我们平时在浏览器中看文章的时候,经常会采集好文章,一键操作,方便快捷。那么怎么能像浏览器书签采集文章一样方便投稿呢?
很容易想到通过浏览器的扩展能力来做到这一点,Chrome插件就提供了这样的能力
什么是 Chrome 扩展程序
官方解释():谷歌插件是用来定制浏览器体验的小程序。它允许用户根据个人需求或偏好自定义 Chrome 的功能和行为,并且它们基于 Web 技术(HTML、JavaScript 和 CSS)构建。
会说话的人话:开发一个web项目,可以嵌入到Chrome浏览器中,可以通过一些特定的API获取一些能力,从而定制自己的插件功能
如何开发Chrome插件一键提交
首先创建一个项目并开发一个贡献页面。
这个项目和普通的 Vue 项目唯一的区别就是在根目录下多了一个 manifest.json 文件。
{ <br /> // 核心代码 <br /> "name": "Zoo!", // 扩展名 <br /> "browser_action": { <br /> "default_popup": "./popup.html" // 点击浏览器右上方插件小图标弹出的内容 html <br /> }, <br /> "content_scripts": [ // 能够在 Web 页面内运行的 javascript 脚本 <br /> { <br /> "matches": [<br /> // 满足什么协议下进行调用 <br /> "http://*/*", <br /> "https://*/*" <br /> ], <br /> "js": [ <br /> "./contentScripts/zdata.js" // 插入到网页的 JS 文件路径 <br /> ], <br /> "run_at": "document_start" // 在document 加载时执行 <br /> } <br /> ] <br />} <br />
这样,当插件打开时,会默认加载popup.html页面的内容,效果如下:
插件本身并不能真正获取当前页面的标题,但是Chrome插件提供了将固定的JS脚本动态插入当前页面的能力。我们可以根据这个机制在当前页面中插入一个JS脚本来获取标题、介绍和URL,然后通过消息机制将获取到的内容返回给插件。
let host = this;<br />// 获取当前窗口 id <br />chrome.tabs.query({<br /> active: true,<br /> currentWindow: true<br />}, function (tabs) {<br /> let tabId = tabs.length ? tabs[0].id : null;<br /> // 向当前页面注入 JavaScript 脚本 <br /> chrome.tabs.executeScript(tabId || null, {<br /> file: './contentScripts/recommend.js'<br /> }, function () {<br /> // 向目标网页进行通信,向 recommend.js 发送一个消息 <br /> chrome.tabs.sendMessage(tabId, {<br /> message: 'GET_TOPIC_INFO',<br /> }, function (response) {<br /> // 获取到返回的文章 title 、url、description <br /> host.article.title = response.title;<br /> host.article.link = response.link;<br /> host.article.description = response.description;<br /> });<br /> });<br />}); <br />
推荐.js *敏*感*词*消息。通过 addListener,我们可以*敏*感*词* sendMessage 发送的消息。在 sendMessage 中定义消息常量可以让我们在接收消息时区分消息。
let doc = document;<br />chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {<br /> if (request.message === 'GET_TOPIC_INFO') {<br /> // 获取 title <br /> let title = document.getElementsByTagName('title')[0].textContent;<br /> let descriptionEl = doc.querySelectorAll('meta[name=description]')[0];<br /> // 获取 描述 <br /> let description = descriptionEl ? descriptionEl.getAttribute('content') : title;<br /> // 发送数据 <br /> sendResponse({<br /> title: title.trim(),<br /> link: location.href,<br /> description: description.trim()<br /> });<br /> } else if (request.message === 'SIGN_RELOAD') {<br /> console.log('request, sender', request, sender);<br /> }<br />}); <br />
// 投稿按钮点击事件 <br />handleRecommendArticle: function () {<br /> let request;<br /> request = ajax({<br /> method: 'post',<br /> url: 'https://XXX/api/post', // 后端接口 <br /> data: {<br /> 'title': this.article.title,<br /> 'desc': this.article.description,<br /> 'category': this.article.category[1] || '默认分类',<br /> 'link': this.article.link,<br /> 'referrer': this.article.reporter<br /> }<br /> });<br />} <br />
效果图:
以上是一个非常轻量级的Chrome插件的实现。基于这样一个Chrome插件,当我们看到喜欢的文章时,可以一键分享给团队的小伙伴~
当文章太多的时候,如果没有有效的管理,文章就会堆得乱七八糟,会让大家失去学习的欲望,那么我们如何分类采集提交的 文章 ,方便同学们找到自己需要的知识体系吗?
标签设计
设计标签分类需要一些时间。主要难点是什么分类维度可以让投稿人快速找到对应的分类,让观众可以根据分类快速找到自己想要的文章,以及如何快速找到过去的文章等.
这就要求我们的分类要通俗易懂,涵盖大部分业务类型文章。最后,我们从基础、语言、架构、选择、工具、总结等多个维度进行分类。
为了能够快速搜索文章,Chrome插件中也集成了分类查看功能。
插件制作完成后,其他同学可以将你的插件安装包安装到浏览器中。因为有墙,所以没有选项可以将插件上传到 Chrome 应用商店。我们在本地安装它。下图为打包后的项目目录结构:
安装步骤:浏览器选择设置->扩展->加载解压后的扩展->选择文件目录。同时,记得开启开发者模式。
Chrome扩展官方详细文档请移步链接()查看
聚合沉淀对于前端项目来说是很常见的,这里就不多说了。主要是能看到每一期的文章,快速分类搜索,统一收录文章入口。其中,前端页面是通过SSR服务端渲染实现的。
定时交货
到这里,小报系统的前端展示页面已经完成了,那么如何让每一期的优质文章更及时方便同学们阅读,让大家在学习中了解新技术适时地开阔眼界。后来我们想到可以通过主动联系、定时提醒等方式主动给队友发日记,所以在以上基础上,设计了一个单独的推送服务,定时推送每周小报到钉钉群和前台——结束邮件组。
const pushToRobot = async ({ data, title, nums }) => {<br /> // 组装发送数据格式 <br /> const links = wrapperFeedcard({ data, nums });<br /> // 发送数据到指定群 <br /> return axios("https://oapi.dingtalk.com/robot/send?", {<br /> method: "post",<br /> params: {<br /> access_token: "XXXX" //前端群 <br /> },<br /> data: {<br /> feedCard: {<br /> links<br /> },<br /> msgtype: "feedCard"<br /> }<br /> })<br />}; <br />
// 创建邮件链接 <br />const nodemailer = require("nodemailer"); <br />let transporter = nodemailer.createTransport({ <br /> service: "qiye.aliyun", <br /> port: 25, // SMTP 端口 <br /> host: "smtp.mxhichina.com", <br /> secureConnection: true, // 使用了 SSL <br /> auth: { <br /> user: "xxx@cai-inc.com", <br /> pass: "xxx" <br /> } <br />}); <br />// 组装发送内容 <br />let mailOptions = { <br /> from: '"政采云前端小报" ', // sender address <br /> to: "ZooTeam@cai-inc.com", // list of receivers <br /> cc: ["ZooTeam@cai-inc.com"], <br /> html: '邮件内容' // html body <br />}; <br />// 邮件发送 <br />transporter.sendMail(mailOptions); <br />
有一天,我们掘金的运营*敏*感*词*告诉我,我们每周五要下班的时候发布文章。这太痛苦了。下班后耽误了我的约会。我说好,我们自己开发一个定时发布功能。如果想知道掘金的定时发布功能如何实现,可以在评论区留言讨论。
整体设计
总结
前端小报系统虽然是一个小系统,但无论是功能设计还是系统设计,都在追逐一个目标,努力促进团队的学习氛围,让团队成员不断成长。希望分享这篇文章能给大家一些启发,如何从一个目标出发去拆解实施,思考如何让工具更好地为人服务。
读两件事
如果你觉得这个内容有启发性,我想请你帮我做两件小事
1.点击“我在看”,让更多人看到这个内容(点击“我在看”,bug -1?)