Node.js数据抓取技术实战示例

news2025/5/17 4:34:31

Node.js常用的库有哪些呢?比如axios或者node-fetch用来发送HTTP请求,cheerio用来解析HTML,如果是动态网页的话可能需要puppeteer这样的无头浏览器。这些工具的组合应该能满足大部分需求。

然后,可能遇到的难点在哪里?比如反爬虫机制,比如验证码、IP封锁,或者需要处理JavaScript渲染的内容。这时候可能需要使用puppeteer来模拟浏览器行为,或者使用代理池来避免IP被封。

在这里插入图片描述

接下来考虑步骤。首先发送请求获取页面内容,然后解析HTML提取所需数据,最后存储数据到文件或数据库。如果是分页的数据,可能需要循环处理多个页面。还需要处理异常情况,比如请求失败、页面结构变化等,这时候需要错误处理和日志记录。

另外,爬虫可能对性能有要求吗?比如并发请求,可以使用Promise.all或者限制并发数的库,比如p-limit,避免同时发送太多请求导致服务器压力过大或被封IP。

数据存储方面,可能需要存到JSON文件、CSV,或者数据库如MongoDB、MySQL,根据用户需求选择。如果是简单需求,保存到文件可能更方便。

还有合法性的问题,提醒用户遵守网站的robots.txt,尊重版权和隐私,避免法律问题。这也是需要注意的地方。

最后,代码示例部分需要简单明了,展示一个完整的流程。比如用axios获取页面,用cheerio解析,提取数据,然后保存到文件。如果是动态内容,用puppeteer的例子。同时给出注意事项,比如处理延迟、错误处理等。

多数用户是初学者,所以代码示例要注释清楚,步骤明确。同时需要提到可能的扩展点,比如处理分页、并发请求、存储到数据库等,让用户知道如何根据需求进一步开发。

总结一下,回答需要涵盖工具选择、步骤分解、代码示例、注意事项以及可能的扩展方向,帮助用户全面了解Node.js抓取数据的流程和要点。

在 Node.js 中实现数据抓取通常涉及 HTTP 请求、HTML 解析和数据处理。以下是详细实现步骤和示例代码:

一、常用工具

  1. HTTP 请求库

    • axios:Promise-based HTTP 客户端
    • node-fetch:类似浏览器 fetch 的实现
    • puppeteer:无头浏览器(用于动态渲染页面)
  2. HTML 解析

    • cheerio:类似 jQuery 的 DOM 操作库
    • jsdom:完整的 DOM 实现
  3. 其他工具

    • p-limit:控制并发请求
    • csv-writer:生成 CSV 文件

二、静态页面抓取示例

const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');

async function fetchData(url) {
  try {
    const { data } = await axios.get(url);
    const $ = cheerio.load(data);
    
    const results = [];
    $('.product-item').each((i, element) => {
      results.push({
        name: $(element).find('.name').text().trim(),
        price: $(element).find('.price').text().trim(),
        link: $(element).find('a').attr('href')
      });
    });

    fs.writeFileSync('products.json', JSON.stringify(results, null, 2));
    console.log('数据抓取完成');
  } catch (error) {
    console.error('抓取失败:', error.message);
  }
}

// 使用示例
fetchData('https://example.com/products');

三、动态页面抓取(使用 Puppeteer)

const puppeteer = require('puppeteer');

async function dynamicScraping(url) {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  
  await page.goto(url, { waitUntil: 'networkidle2' });
  
  // 执行页面内 JavaScript
  const data = await page.evaluate(() => {
    return Array.from(document.querySelectorAll('.user-card'))
      .map(card => ({
        username: card.querySelector('.username').innerText,
        bio: card.querySelector('.bio').innerText
      }));
  });

  await browser.close();
  return data;
}

// 使用示例
dynamicScraping('https://example.com/users')
  .then(data => console.log(data))
  .catch(console.error);

四、高级技巧

  1. 处理分页
async function paginatedScraping(baseUrl, totalPages) {
  const results = [];
  
  for (let page = 1; page <= totalPages; page++) {
    const url = `${baseUrl}?page=${page}`;
    const data = await fetchData(url);
    results.push(...data);
    await new Promise(resolve => setTimeout(resolve, 2000)); // 延迟防止封禁
  }
  
  return results;
}
  1. 并发控制
const pLimit = require('p-limit');
const limit = pLimit(3); // 最大并发数

async function concurrentScraping(urls) {
  const promises = urls.map(url => 
    limit(() => fetchData(url))
  );
  return Promise.all(promises);
}
  1. 代理配置
const axiosInstance = axios.create({
  proxy: {
    host: 'proxy-server',
    port: 8080,
    auth: {
      username: 'your_user',
      password: 'your_pass'
    }
  }
});

五、数据存储选项

  1. JSON 文件
fs.writeFileSync('data.json', JSON.stringify(data));
  1. CSV 文件
const createCsvWriter = require('csv-writer').createObjectCsvWriter;

const csvWriter = createCsvWriter({
  path: 'data.csv',
  header: [
    {id: 'name', title: 'NAME'},
    {id: 'price', title: 'PRICE'}
  ]
});

csvWriter.writeRecords(data);
  1. 数据库存储(MongoDB 示例)
const mongoose = require('mongoose');

const productSchema = new mongoose.Schema({
  name: String,
  price: Number,
  link: String
});

const Product = mongoose.model('Product', productSchema);

async function saveToDB(data) {
  await mongoose.connect('mongodb://localhost:27017/scraping');
  await Product.insertMany(data);
  await mongoose.disconnect();
}

六、反爬虫对策

  1. 设置合理的请求头
headers: {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
  'Accept-Language': 'en-US,en;q=0.9'
}
  1. 使用随机延迟
function randomDelay(min, max) {
  return new Promise(resolve => 
    setTimeout(resolve, Math.random() * (max - min) + min)
  );
}
  1. 处理 Cookie
const jar = new tough.CookieJar();
axios.get(url, {
  jar: jar,
  withCredentials: true
});

七、错误处理最佳实践

async function robustScraping(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await fetchData(url);
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, 5000 * (i + 1)));
    }
  }
}

注意事项

  1. 遵守 robots.txt 规则
  2. 尊重网站的服务条款
  3. 控制请求频率(建议 2-5 秒/请求)
  4. 处理敏感数据需符合 GDPR 等法规
  5. 使用 try/catch 处理网络错误
  6. 定期检查选择器是否有效

根据具体需求可以组合这些技术,简单的静态页面使用 cheerio + axios 即可,复杂场景(SPA、需要登录)则需要 puppeteer。对于大规模抓取建议使用分布式架构(Redis 队列 + 多 Worker)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2376423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows10 安装 QT

本地环境有个qt文件&#xff0c;这里是5.14.2 打开一个cmd窗口并指定到该文件根目录下 .\qt-opensource-windows-x86-5.14.2.exe --mirror https://mirrors.ustc.edu.cn/qtproject 执行上面命令 记住是文件名&#xff0c;记住不要傻 X的直接复制&#xff0c;是你的文件名 点击…

WordPress 和 GPL – 您需要了解的一切

如果您使用 WordPress&#xff0c;GPL 对您来说应该很重要&#xff0c;您也应该了解它。查看有关 WordPress 和 GPL 的最全面指南。 您可能听说过 GPL&#xff08;通常被称为 WordPress 的权利法案&#xff09;&#xff0c;但很可能并不完全了解它。这是有道理的–这是一个复杂…

C++书本摆放 2024年信息素养大赛复赛 C++小学/初中组 算法创意实践挑战赛 真题详细解析

目录 C++书本摆放 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、运行结果 五、考点分析 六、 推荐资料 1、C++资料 2、Scratch资料 3、Python资料 C++书本摆放 2024年信息素养大赛 C++复赛真题 一、题目要求 1、编程实现 中科智慧科技…

RabbitMQ 核心概念与消息模型深度解析(一)

一、RabbitMQ 是什么 在当今分布式系统盛行的时代&#xff0c;消息队列作为一种至关重要的中间件技术&#xff0c;扮演着实现系统之间异步通信、解耦和削峰填谷等关键角色 。RabbitMQ 便是消息队列领域中的佼佼者&#xff0c;是一个开源的消息代理和队列服务器&#xff0c;基于…

论文阅读笔记——双流网络

双流网络论文 视频相比图像包含更多信息&#xff1a;运动信息、时序信息、背景信息等等。 原先处理视频的方法&#xff1a; CNN LSTM&#xff1a;CNN 抽取关键特征&#xff0c;LSTM 做时序逻辑&#xff1b;抽取视频中关键 K 帧输入 CNN 得到图片特征&#xff0c;再输入 LSTM&…

LabVIEW在电子电工教学中的应用

在电子电工教学领域&#xff0c;传统教学模式面临诸多挑战&#xff0c;如实验设备数量有限、实验过程存在安全隐患、教学内容更新滞后等。LabVIEW 作为一款功能强大的图形化编程软件&#xff0c;为解决这些问题提供了创新思路&#xff0c;在电子电工教学的多个关键环节发挥着重…

Vue3 怎么在ElMessage消息提示组件中添加自定义icon图标

1、定义icon组件代码&#xff1a; <template><svg :class"svgClass" aria-hidden"true"><use :xlink:href"iconName" :fill"color"/></svg> </template><script> export default defineComponen…

生活破破烂烂,AI 缝缝补补(附提示词)

写在前面&#xff1a;​【Fire 计算器】已上线&#xff0c;快算算财富自由要多少​ 现实不总温柔&#xff0c;愿你始终自渡。 请永远拯救自己于水火之中。 毛绒风格提示词&#xff08;供参考&#xff09;&#xff1a; 1. 逼真毛绒风 Transform this image into a hyperrealist…

张 。。 通过Token实现Loss调优prompt

词编码模型和 API LLM不匹配,采用本地模型 理性中性案例(针对中性调整比较合理) 代码解释:Qwen2模型的文本编码与生成过程 这段代码展示了如何使用Qwen2模型进行文本的编码和解码操作。 模型加载与初始化 from transformers import AutoModelForCausalLM, AutoTokenizer

JVM学习专题(一)类加载器与双亲委派

目录 1、JVM加载运行全过程梳理 2、JVM Hotspot底层 3、war包、jar包如何加载 4、类加载器 我们来查看一下getLauncher&#xff1a; 1.我们先查看getExtClassLoader() 2、再来看看getAppClassLoader(extcl) 5、双亲委派机制 1.职责明确&#xff0c;路径隔离​&#xff…

PyTorch API 9 - masked, nested, 稀疏, 存储

文章目录 torch.randomtorch.masked简介动机什么是 MaskedTensor&#xff1f; 支持的运算符一元运算符二元运算符归约操作查看与选择函数 torch.nested简介构造方法数据布局与形状支持的操作查看嵌套张量的组成元素填充张量的相互转换形状操作注意力机制 与 torch.compile 的配…

进程相关面试题20道

一、基础概念与原理 1.进程的定义及其与程序的本质区别是什么&#xff1f; 答案&#xff1a;进程是操作系统分配资源的基本单位&#xff0c;是程序在数据集合上的一次动态执行过程。核心区别&#xff1a;​ 动态性&#xff1a;程序是静态文件&#xff0c;进程是动态执行实例…

Linux复习笔记(五) 网络服务配置(dhcp)

二、网络服务配置 2.5 dhcp服务配置&#xff08;不涉及实际操作&#xff09; 要求&#xff1a;知道原理和常见的参数配置就行 2.5.1 概述DHCP&#xff08;Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议&#xff09; DHCP&#xff08;Dynamic Host Conf…

windows版redis的使用

redis下载 Releases microsoftarchive/redishttps://github.com/microsoftarchive/redis/releases redis的启动和停止 进入路径的cmd 启动&#xff1a;redis-server.exe redis.windows.conf 停止&#xff1a;ctrlc 连接redis 指定要连接的IP和端口号 -h IP地址 -p 端口…

Java版OA管理系统源码 手机版OA系统源码

Java版OA管理系统源码 手机版OA系统源码 一&#xff1a;OA系统的主要优势 1. 提升效率 减少纸质流程和重复性工作&#xff0c;自动化处理常规事务&#xff0c;缩短响应时间。 2. 降低成本 节省纸张、打印、通讯及人力成本&#xff0c;优化资源分配。 3. 规范管理 固化企…

NineData 社区版 V4.1.0 正式发布,新增 4 条迁移链路,本地化数据管理能力再升级

NineData 社区版 V4.1.0 正式更新发布。本次通过新增 4 条迁移链路扩展、国产数据库深度适配、敏感数据保护增强‌等升级&#xff0c;进一步巩固了其作为高效、安全、易用的数据管理工具的定位。无论是开发测试、数据迁移&#xff0c;还是多环境的数据管理&#xff0c;NineData…

进阶2_1:QT5多线程与定时器共生死

1、在widget.ui中使用 LCD Number控件 注意&#xff1a;若 LCD 控件不是多线程&#xff0c;LCD控件则会瞬间自增到最大的数值&#xff0c;如上图&#xff0c;说明两者都是多线程处理 2、实现方式 1、创建 LCD 控件并修改为 LCD1 2、创建任务类 mytask. h&#xff0c;对任务类…

在虚拟机Ubuntu18.04中安装NS2教程及应用

NS2简介 一、主要组成部分&#xff1a; 1.NS2&#xff1a;模拟器本身&#xff0c;负责执行TCL脚本进行模拟&#xff0c;并生成trace文件输出结果。 2.NAM&#xff1a;网络动画模拟器&#xff0c;用于将模拟结果可视化。 二、使用的语言&#xff1a; 1.C&#xff1a;NS2中最重要…

VBA —— 第6章子程序与函数

子程序&#xff1a;实现特定功能的程序代码块 子程序语法&#xff1a; [修饰符] Sub 子程序名称([参数1&#xff0c;参数2&#xff0c;参数3]) 代码块 End Sub 子程序如何调用&#xff1a; 1 . 子程序名 [参数1&#xff0c;参数2&#xff0c;...] 2. Call 子程序名 [(参…

全新开发-iVX图形化编程VS完整IDE

本文针对传统软件开发的效率与可控性矛盾&#xff0c;系统阐释 iVX"图形化编程 全栈 IDE" 的复合架构如何突破行业瓶颈。通过 "可视化建模 - 标准代码生成 - 独立运行" 的技术闭环&#xff0c;iVX 实现开发效率提升 60% 与源码完全可控的双重目标。研究揭…