部署与调度Node.js爬虫:从本地执行到云端集成

部署与调度Node.js爬虫:从本地执行到云端集成

本教程详细指导如何部署和调度一个基于node.js的网页爬虫,使其能够每日自动运行并将其数据提供给前端应用。文章将区分客户端与服务器端javascript的运行环境,介绍本地任务调度方法,并探讨将爬虫集成到在线服务以实现数据共享的策略,同时涵盖数据持久化、cors处理及部署最佳实践。

1. 理解Node.js爬虫的运行环境

首先,我们需要明确一点:您所编写的爬虫代码(使用 puppeteer 和 fs 模块)是一个基于Node.js环境运行的服务器端脚本,而非在浏览器中执行的客户端JavaScript。

客户端JavaScript:在用户的浏览器中运行,主要负责页面交互、DOM操作等,无法直接访问本地文件系统或执行外部程序。服务器端Node.js:在服务器或本地计算机上运行,可以执行文件I/O操作(如 fs.writeFile),启动无头浏览器(如 puppeteer),处理网络请求等。

因此,要让您的 index.js 每日自动运行,并使其生成的数据可供前端页面访问,需要采取与部署静态网站不同的策略。

以下是您提供的Node.js爬虫代码示例:

const puppeteer = require('puppeteer');const fs = require('fs');// 爬取第一个数据源(async () => {  const browser = await puppeteer.launch();  const page = await browser.newPage();  await page.goto('https://br.advfn.com/investimentos/futuros/di-depositos-interfinanceiros/cotacoes',{    waitUntil: 'load',    timeout: 0  });  const textNode = await page.evaluate(()=>{    const nodeText = document.querySelector(".even.first").innerText;    const text = [nodeText];    return text  });  fs.writeFile('arreglo2.json', JSON.stringify(textNode), err =>{    if (err) throw new Error ('algo deu errado')      console.log('arreglo2.json saved successfully')  })  await browser.close(); // 关闭浏览器实例})();// 爬取第二个数据源(async () => {  const browser = await puppeteer.launch();  const page = await browser.newPage();  await page.goto('https://br.tradingview.com/symbols/TVC-DXY/',{    waitUntil: 'load',    timeout: 0  });  const textNode = await page.evaluate(()=>{    const nodeText = document.querySelector(".js-quote-ticker.tv-site-table__row.tv-widget-watch-list__row:nth-child(2)").children[1].children[1].children[0].innerHTML;    const text = [nodeText];    return text  });  fs.writeFile('arreglo.json', JSON.stringify(textNode), err =>{    if (err) throw new Error ('algo deu errado')      console.log('arreglo.json saved successfully')  })  await browser.close(); // 关闭浏览器实例})();// 爬取第三个数据源(async () => {  const browser = await puppeteer.launch();  const page = await browser.newPage();  await page.goto('https://br.advfn.com/bolsa-de-valores/fx/USDBRL/cotacao',{    waitUntil: 'load',    timeout: 0  });  const textNode = await page.evaluate(()=>{    const nodeText = document.querySelector(".qs-current-price").innerText;    const text = [nodeText];    return text  });  fs.writeFile('cotacaoFechamento.json', JSON.stringify(textNode), err =>{    if (err) throw new Error ('algo deu errado')      console.log('cotacaoFechamento.json saved successfully')  })  await browser.close(); // 关闭浏览器实例})();

请注意,为了避免资源泄露,在每个 puppeteer 实例使用完毕后,都应调用 await browser.close(); 关闭浏览器。

2. 本地调度方案:Windows任务计划程序

如果您希望爬虫在自己的Windows电脑上每日定时运行,最直接的方法是使用Windows任务计划程序(Task Scheduler)。

操作步骤:

打开任务计划程序: 在Windows搜索栏输入“任务计划程序”并打开。创建基本任务: 在右侧“操作”面板中选择“创建基本任务…”。任务命名与描述:名称: 例如 “每日爬虫任务”。描述: 简要说明任务用途。配置触发器:选择“每天”。设置起始日期和时间,例如每日“上午 8:00:00”。点击“下一步”。定义操作:选择“启动程序”。程序或脚本: 填写您的Node.js安装路径中的 node.exe。通常在 C:Program Filesnodejsnode.exe 或您自定义的安装路径。添加参数(可选): 填写您的爬虫脚本路径,例如 C:UsersYourUserpathtoyourprojectindex.js。请确保使用完整路径。起始于(可选): 填写您的爬虫脚本所在目录的路径,例如 C:UsersYourUserpathtoyourproject。这对于脚本中涉及相对路径的文件操作很重要。点击“下一步”。完成: 检查任务摘要,确认无误后点击“完成”。

现在,您的Node.js爬虫将在每天上午8点自动运行,并将数据保存到指定的JSON文件中。

3. 将爬虫数据集成到前端应用

爬虫在本地运行并生成JSON文件后,如何让您的静态HTML页面访问这些数据呢?这涉及到将数据“服务”出去。

3.1 本地开发环境的CORS问题

您提到在 C:// 目录下运行爬虫时遇到CORS错误,而在XAMPP环境下则正常。这是因为:

本地文件协议 (file://):当您直接在浏览器中打开HTML文件时,它使用 file:// 协议。出于安全考虑,浏览器严格限制 file:// 页面通过 XMLHttpRequest 或 fetch API 访问其他本地文件(即使是同一目录下的文件)。这被视为跨域请求,因此会触发CORS错误。HTTP服务器 (XAMPP):XAMPP提供了一个本地HTTP服务器。当您通过 http://localhost/your_project/index.html 访问页面时,它运行在 http:// 协议下。在这种情况下,HTML页面可以自由地请求同一域(localhost)下的其他资源(包括爬虫生成的JSON文件),因为它们不再是跨域请求。

因此,要让前端页面访问爬虫生成的数据,您需要一个HTTP服务器来提供这些JSON文件。

3.2 部署策略

a. 简单的Node.js HTTP服务器

您可以编写一个简单的Node.js服务器来提供爬虫生成的JSON文件。

创建 server.js 文件: 在您的项目根目录创建一个 server.js 文件。

const http = require('http');const fs = require('fs');const path = require('path');const hostname = '127.0.0.1'; // 或 '0.0.0.0' 允许外部访问const port = 3000;const dataDir = __dirname; // 假设JSON文件与server.js在同一目录const server = http.createServer((req, res) => {  // 允许跨域请求,重要!  res.setHeader('Access-Control-Allow-Origin', '*'); // 生产环境请指定具体域名  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');  res.setHeader('Access-Control-Allow-Credentials', true);  // 处理OPTIONS请求(CORS预检请求)  if (req.method === 'OPTIONS') {    res.writeHead(204);    res.end();    return;  }  if (req.url === '/data/arreglo2.json') {    fs.readFile(path.join(dataDir, 'arreglo2.json'), (err, data) => {      if (err) {        res.statusCode = 404;        res.setHeader('Content-Type', 'text/plain');        res.end('File not found');        return;      }      res.statusCode = 200;      res.setHeader('Content-Type', 'application/json');      res.end(data);    });  } else if (req.url === '/data/arreglo.json') {     fs.readFile(path.join(dataDir, 'arreglo.json'), (err, data) => {      if (err) {        res.statusCode = 404;        res.setHeader('Content-Type', 'text/plain');        res.end('File not found');        return;      }      res.statusCode = 200;      res.setHeader('Content-Type', 'application/json');      res.end(data);    });  } else if (req.url === '/data/cotacaoFechamento.json') {     fs.readFile(path.join(dataDir, 'cotacaoFechamento.json'), (err, data) => {      if (err) {        res.statusCode = 404;        res.setHeader('Content-Type', 'text/plain');        res.end('File not found');        return;      }      res.statusCode = 200;      res.setHeader('Content-Type', 'application/json');      res.end(data);    });  } else {    res.statusCode = 404;    res.setHeader('Content-Type', 'text/plain');    res.end('Not Found');  }});server.listen(port, hostname, () => {  console.log(`Server running at http://${hostname}:${port}/`);});

运行服务器: 在终端中运行 node server.js。

前端获取数据: 您的HTML页面中的JavaScript可以通过 fetch API 请求数据:

fetch('http://127.0.0.1:3000/data/arreglo2.json')  .then(response => response.json())  .then(data => {    console.log('Fetched arreglo2.json:', data);    // 处理数据显示逻辑  })  .catch(error => console.error('Error fetching data:', error));

b. 云服务部署与调度

为了实现更稳定、可扩展的在线服务,您可以将爬虫部署到云平台。

Serverless 函数 (如AWS Lambda, Vercel Serverless Functions, Netlify Functions)优点:按需付费,无需管理服务器,可配置定时触发器(如AWS CloudWatch Events),非常适合定时运行的短任务。挑战:puppeteer 依赖无头浏览器,部署到Serverless环境需要额外配置(如使用 chrome-aws-lambda)。文件系统通常是临时的,JSON数据需要保存到持久化存储(如AWS S3、数据库)。PaaS 平台 (如Heroku, Render, Railway)优点:简化部署流程,支持Node.js应用,可配置定时任务(通常通过平台提供的附加组件或自定义脚本)。部署:您可以将爬虫和上述的Node.js HTTP服务器一起部署为一个应用。挑战:免费层级可能有限制,文件系统通常也是临时的,需考虑数据持久化。虚拟机/容器 (如AWS EC2, Docker, Kubernetes)优点:完全控制运行环境,可以安装所有依赖,适用于复杂或资源密集型爬虫。部署:您可以在虚拟机上安装Node.js,并将爬虫和HTTP服务器部署上去。调度可以使用Linux的 cron 任务或Windows的任务计划程序。挑战:管理成本较高,需要一定的DevOps知识。

数据持久化考量:在云环境中,服务器的文件系统通常是临时的。这意味着每次应用重启或Serverless函数调用时,之前保存的JSON文件可能会丢失。为了确保数据持久性,您应该考虑将爬取到的数据存储到:

云存储服务:如AWS S3、Google Cloud Storage。数据库:如MongoDB、PostgreSQL、MySQL。Redis:作为缓存或临时存储。

4. 关键注意事项与最佳实践

错误处理与日志:对于自动化任务,完善的错误处理和日志记录至关重要。当爬虫失败时,您需要知道原因并及时收到通知。环境配置:使用环境变量来管理端口号、数据存储路径、API密钥等配置信息,避免硬编码。CORS策略:如果您部署了自定义的Node.js HTTP服务器,请务必正确配置 Access-Control-Allow-Origin 头,以允许您的前端域名访问数据。在生产环境中,不要使用 *,而应指定具体的前端域名。资源管理:puppeteer 启动无头浏览器会消耗大量内存和CPU。确保您的服务器或云函数有足够的资源。在每次爬取任务完成后,务必调用 browser.close() 释放资源。部署自动化:随着项目迭代,手动部署会变得繁琐。考虑使用CI/CD工具(如GitHub Actions, GitLab CI/CD)自动化代码测试、构建和部署过程。爬虫道德与法律:在进行网页爬取时,请务必遵守目标网站的 robots.txt 协议,尊重网站的使用条款,并注意数据隐私和版权问题。避免对网站造成过大负载。

总结

部署和调度一个Node.js网页爬虫需要您理解其服务器端运行的特性。对于本地运行,Windows任务计划程序是一个简单有效的调度工具。而要将数据提供给在线前端应用,您需要一个HTTP服务器来提供这些JSON文件。根据您的需求和技术栈,可以选择部署简单的Node.js HTTP服务器,或利用云平台的Serverless函数、PaaS服务等更专业的解决方案。在任何部署中,数据持久化、错误处理和CORS配置都是不可忽视的关键点。

以上就是部署与调度Node.js爬虫:从本地执行到云端集成的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1598031.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
HTML5模板标签怎么用_HTML5template标签实现内容模板的方法
上一篇 2025年12月23日 12:34:35
Ionic/Angular框架中:host CSS样式有效覆盖指南
下一篇 2025年12月23日 12:35:01

相关推荐

  • 修复Django电商项目中AJAX过滤产品列表图片不显示问题

    在Django电商项目中,当使用AJAX动态加载过滤后的产品列表时,常遇到图片无法正常显示的问题。这通常是由于前端模板中图片加载方式(如data-setbg属性结合JavaScript库)与AJAX动态内容更新机制不兼容所致。解决方案是直接在AJAX返回的HTML中使用标准的标签来渲染图片,确保浏览…

    2026年5月10日
    000
  • 开源免费PHP工具 PHP开发效率提升利器

    推荐开源免费PHP开发工具以提升效率:VS Code、Sublime Text轻量高效,PhpStorm专业强大;调试用Xdebug、Kint、Ray;依赖管理选Composer;代码质量工具包括PHPStan、Psalm、PHP_CodeSniffer;数据库管理可用%ignore_a_1%MyA…

    2026年5月10日
    000
  • Golang JSON序列化:控制敏感字段暴露的最佳实践

    本教程探讨golang中如何高效控制结构体字段在json序列化时的可见性。当需要将包含敏感信息的结构体数组转换为json响应时,通过利用`encoding/json`包提供的结构体标签,特别是`json:”-“`,可以轻松实现对特定字段的忽略,从而避免敏感数据泄露,确保api…

    2026年5月10日
    000
  • 怎么在PHP代码中实现图片上传功能_PHP图片上传功能实现与安全处理教程

    首先创建含enctype的HTML表单,再用PHP接收文件,检查目录、移动临时文件,验证类型与大小,生成唯一文件名,并调整php.ini限制以确保上传成功。 如果您尝试在PHP项目中添加图片上传功能,但服务器无法正确接收或保存文件,则可能是由于表单配置、文件处理逻辑或安全限制的问题。以下是实现该功能…

    2026年5月10日
    100
  • HTML如何隐藏滚动条或去除滚动条

    滚动条可以存在也可以不存在,本文主要介绍了html 隐藏滚动条和去除滚动条的方法的相关资料,大家一起来学习一下html隐藏滚动条或去除滚动条的方法吧。 1. html 标签加属性 XML/HTML Code复制内容到剪贴板 2.body中加入以下代码 立即学习“前端免费学习笔记(深入)”; html…

    用户投稿 2026年5月10日
    000
  • vscode上怎么运行html_vscode上运行html步骤【指南】

    首先保存文件为.html格式,再通过浏览器或Live Server插件打开预览;推荐安装Live Server实现本地服务器运行与实时刷新,提升开发体验。 在 VS Code 上运行 HTML 文件并不需要复杂的配置,只需几个简单步骤即可预览页面效果。VS Code 本身是一个代码编辑器,不直接运行…

    2026年5月10日
    100
  • 修复点击时按钮抖动:CSS垂直对齐实践

    本文探讨了在Web开发中,交互式按钮(如播放/暂停按钮)在点击时发生意外垂直位移的问题。通过分析CSS样式变化对元素布局的影响,我们发现这是由于按钮不同状态下的边框样式和内边距改变,以及默认的垂直对齐行为共同作用所致。核心解决方案是利用CSS的vertical-align属性,将其设置为middle…

    2026年5月10日
    000
  • 页面中文本域的值怎么设置

    标签定义多行的文本输入控件。 文本区中可容纳无限数量的文本,其中的文本的默认字体是等宽字体(通常是 Courier)。 可以通过 cols 和 rows 属性来规定 textarea 的尺寸,不过更好的办法是使用 CSS 的 height 和 width 属性。 注释:在文本输入区内的文本行间,用 …

    2026年5月10日
    000
  • 使用 Jupyter Notebook 进行探索性数据分析

    Jupyter Notebook通过单元格实现代码与Markdown结合,支持数据导入(pandas)、清洗(fillna)、探索(matplotlib/seaborn可视化)、统计分析(describe/corr)和特征工程,便于记录与分享分析过程。 Jupyter Notebook 是进行探索性…

    2026年5月10日
    000
  • 如何在HTML中插入表单元素_HTML表单控件与输入类型使用指南

    HTML表单通过标签构建,包含action和method属性定义数据提交目标与方式,常用input类型如text、password、email等适配不同输入需求,配合label、required、placeholder提升可用性,结合textarea、select、button等控件实现完整交互,是…

    2026年5月10日
    000
  • 前端缓存策略与JavaScript存储管理

    根据数据特性选择合适的存储方式并制定清晰的读写与清理逻辑,能显著提升前端性能;合理运用Cookie、localStorage、sessionStorage、IndexedDB及Cache API,结合缓存策略与定期清理机制,可在保证用户体验的同时避免安全与性能隐患。 前端缓存和JavaScript存…

    2026年5月10日
    100
  • HTML5网页如何实现手势操作 HTML5网页移动端交互的处理技巧

    首先利用原生touch事件实现滑动判断,再通过preventDefault解决滚动冲突,接着引入Hammer.js处理复杂手势,最后通过优化点击区域、避免事件冲突和增加视觉反馈提升体验。 在移动端浏览器中,HTML5网页可以通过触摸事件实现手势操作,提升用户体验。虽然原生JavaScript提供了基…

    2026年5月10日
    000
  • 深入理解 Express.js 中 next() 参数的作用与中间件机制

    本文深入探讨 express.js 中间件函数中的 `next()` 参数。它负责将控制权传递给请求-响应周期中的下一个中间件或路由处理程序。文章将详细解释 `next()` 的工作原理、中间件的注册与执行顺序,以及不正确使用 `next()` 可能导致请求挂起的风险,并通过代码示例和实际应用场景,…

    2026年5月10日
    000
  • Python命令怎样使用profile分析脚本性能 Python命令性能分析的基础教程

    使用Python的cProfile模块分析脚本性能最直接的方式是通过命令行执行python -m cProfile your_script.py,它会输出每个函数的调用次数、总耗时、累积耗时等关键指标,帮助定位性能瓶颈;为进一步分析,可将结果保存为文件python -m cProfile -o ou…

    2026年5月10日
    000
  • PHP动态生成表单输入与POST数据获取实践指南

    本教程详细阐述了如何在php中根据动态数据源(如数据库值)生成多个表单输入框,并演示了如何通过post方法准确无误地获取这些动态生成的输入值。文章强调了正确的输入框命名策略,避免了常见的命名误区,并提供了完整的代码示例,确保开发者能够高效处理动态表单数据。 动态生成表单输入 在Web开发中,我们经常…

    2026年5月10日
    000
  • JavaScript 闭包:理解闭包原理与内存泄漏问题

    闭包是函数访问其外部作用域变量的能力,即使外部函数已执行完毕。如 inner 函数引用 outer 中的 count,形成闭包,使变量持久存在。闭包本身无害,但可能因延长变量生命周期导致内存泄漏,例如事件监听器引用大对象时。若未及时清理 DOM 事件或定时器,闭包会阻止垃圾回收,造成内存占用过高。解…

    2026年5月10日
    000
  • JavaScript 动态菜单点击高亮效果实现教程

    本教程详细介绍了如何使用 JavaScript 实现动态菜单的点击高亮功能。通过事件委托和状态管理,当用户点击菜单项时,被点击项会高亮显示(绿色),同时其他菜单项恢复默认样式(白色)。这种方法避免了不必要的DOM操作,提高了性能和代码可维护性,确保了无论点击方向如何,功能都能稳定运行。 动态菜单高亮…

    2026年5月10日
    200
  • c++如何实现UDP通信_c++基于UDP的网络通信示例

    UDP通信基于套接字实现,适用于实时性要求高的场景。1. 流程包括创建套接字、绑定地址(接收方)、发送(sendto)与接收(recvfrom)数据、关闭套接字;2. 服务端监听指定端口,接收客户端消息并回传;3. 客户端发送消息至服务端并接收响应;4. 跨平台需处理Winsock初始化与库链接,编…

    2026年5月10日
    000
  • html5怎么画实线_HTML5用CSS border-style:solid画元素实线边框【绘制】

    可通过CSS的border-style属性设为solid添加实线边框:一、内联样式用border:2px solid #000;二、内部样式表统一设置如div{border:1px solid #333};三、外部CSS文件定义.my-box{border:3px solid red}并引入;四、单…

    2026年5月10日
    200
  • 谷歌浏览器如何截图 谷歌浏览器页面截图技巧

    谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧

    使用谷歌浏览器的开发者工具截图步骤:1. 按ctrl+shift+i(windows/linux)或cmd+option+i(mac)打开开发者工具。2. 点击右上角三个点,选择”更多工具”,再选择”截图”。3. 选择截取整个页面。推荐的谷歌浏览器扩展…

    2026年5月10日 用户投稿
    100

发表回复

登录后才能评论
关注微信