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

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' });// 执行页面内 JavaScriptconst 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.mzph.cn/news/906409.shtml

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

相关文章

数据结构(3)线性表-链表-单链表

我们学习过顺序表时&#xff0c;一旦对头部或中间的数据进行处理&#xff0c;由于物理结构的连续性&#xff0c;为了不覆盖&#xff0c;都得移&#xff0c;就导致时间复杂度为O&#xff08;n&#xff09;&#xff0c;还有一个潜在的问题就是扩容&#xff0c;假如我们扩容前是10…

【Unity】DOTween的常用函数解释

DOTween插件常用函数解释 1.DOTween.To&#xff08;通用变化动画&#xff09; 解释&#xff1a;将某一个值在一定的时间内变化到另一个值&#xff08;通用的函数&#xff09;&#xff0c;可用于大部分的动画变化 使用示例&#xff1a; using UnityEngine; using DG.Tweenin…

数据结构测试模拟题(1)

1、约瑟夫问题 #include<bits/stdc.h> using namespace std; const int N25; int e[N],ne[N],head-1,idx1; int n,m; void add_to_head(int x){e[idx]x;ne[idx]head;headidx; } void add(int k,int x){e[idx]x;ne[idx]ne[k];ne[k]idx; } int main(){cin>>n>>…

Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)

文章目录 Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)需求方法1:使用Helm覆盖值方法2: 在Lens中临时修改Deployment配置步骤 1: 创建 Docker Registry Secret步骤 2: 在 Deployment 中引用 Secret参考资料Helm配置之为特定Deployment配置特定Docker仓库(覆…

BERT 作为Transformer的Encoder 为什么采用可学习的位置编码

摘要 BERT 在位置编码上与原始 Transformer 论文中的 sin/cos 公式不同&#xff0c;选择了可学习&#xff08;learned&#xff09;的位置嵌入方案。本文将从 Transformer 原始位置编码选项入手&#xff0c;分析 BERT 选择 learned positional embeddings 的四大核心原因&#x…

【Linux 学习计划】-- gcc、g++、动静态库链接

目录 什么是gcc、g gcc、g 相关操作详解 预处理、编译、汇编、链接来源 动静态链接是什么 结语 什么是gcc、g gcc、g其实就是编译器&#xff0c;是帮助我们从.c或者.cc&#xff0c;.cpp文件编译成可执行程序的 其中&#xff0c;我们如果要编译c语言文件的话&#xff0c;…

前端读取本地项目中 public/a.xlsx 文件中的数据 vue3

前端读取本地项目中 public/a.xlsx 文件中的数据 vue3 项目中需要在 Vue3 项目中读取 public/a.xlsx 文件&#xff0c;可以使用 fetch API 来获取文件内容 一、安装 xlsx 首先&#xff0c;你需要安装 xlsx 库&#xff1a; npm install xlsx二、在需要用的页面里引入xlsx im…

MySQL:to many connections连接数过多

当你遇到 MySQL: Too many connections 错误时&#xff0c;意味着当前连接数已达到 MySQL 配置的最大限制。这通常是由于并发连接过多或连接未正确关闭导致的。 一、查看当前连接数 查看 MySQL 当前允许的最大连接数 SHOW VARIABLES LIKE max_connections;查看当前使用的最大…

2024年热门AI趋势及回顾

人工智能的崛起 2024 年可能会被铭记为人工智能不再是一种技术新奇事物&#xff0c;而是成为现实的一年。微软、Salesforce 和 Intuit 等巨头将人工智能融入主流企业解决方案&#xff1b;从文案写作到数据分析&#xff0c;专门的人工智能应用程序和服务如雨后春笋般涌现&#…

LangFlow技术深度解析:可视化编排LangChain应用的新范式 -(2)流编辑器系统

Flow Editor System | langflow-ai/langflow | DeepWiki 流编辑器系统 相关源文件 流编辑器系统是 Langflow 的核心交互式组件&#xff0c;允许用户直观地创建、编辑和管理 LLM 驱动的应用程序。它提供了一个直观的画布&#xff0c;用户可以在其中添加节点、将其与边缘连接并…

驱动-定时-秒-字符设备

文章目录 目的相关资料参考实验驱动程序-timer_dev.c编译文件-Makefile测试程序-timer.c分析 加载驱动-运行测试程序总结 目的 通过定时器timer_list、字符设备、规避竞争关系-原子操作&#xff0c;综合运用 实现一个程序&#xff0c;加深之前知识的理解。 实现字符设备驱动框…

[Java实战]Spring Boot整合Kafka:高吞吐量消息系统实战(二十七)

[Java实战]Spring Boot整合Kafka&#xff1a;高吞吐量消息系统实战&#xff08;二十七&#xff09; 一、引言 Apache Kafka作为一款高吞吐量、低延迟的分布式消息队列系统&#xff0c;广泛应用于实时数据处理、日志收集和事件驱动架构。结合Spring Boot的自动化配置能力&…

Kotlin Multiplatform--04:经验总结(持续更新)

Kotlin Multiplatform--04&#xff1a;经验总结&#xff08;持续更新&#xff09; 引言 引言 本章用来记载笔者开发过程中的一些经验总结 一、Ktor设置Header 在官方文档中&#xff0c;想要设置Header的示例代码如下&#xff1a; client.get("https://ktor.io&qu…

在 Ubuntu 系统中,将 JAR 包安装为服务

在 Ubuntu 系统中&#xff0c;将 JAR 包安装为服务可以通过 systemd 来实现。以下是详细的操作步骤&#xff1a; 准备工作 确保 JAR 文件路径和 Java 运行时环境已准备好。验证 Java 是否可用&#xff1a; java -version创建 systemd 服务文件 systemd 的服务文件通常位于 …

电商项目-商品微服务-品牌管理微服务开发

一、功能分析 品牌管理微服务包括&#xff1a; &#xff08;1&#xff09;查询全部列表数据 &#xff08;2&#xff09;根据ID查询实体数据 &#xff08;3&#xff09;增加 &#xff08;4&#xff09;修改 &#xff08;5&#xff09;删除 &#xff08;6&#xff09;分页…

Spring Boot开发—— 整合Lucene构建轻量级毫秒级响应的全文检索引擎

文章目录 一、为什么选择 Lucene?轻量级搜索的底层密码二、核心原理:Lucene 的倒排索引2.1 倒排索引:速度之源2.2 段合并优化策略三、Spring Boot集成Lucene实战3.1 依赖配置3.2 实体与索引设计3.3 核心索引服务(含异常处理)3.4 使用示例(测试类)四、高级优化技巧4.1 索…

SpringBootDay1|面试题

目录 一、springboot框架 1、什么是springboot 2、Spring Boot的主要优点 3、springboot核心注解 4、定义banner&#xff08;springboot的logo&#xff09; 5、springboot配置文件 6、springboot 整合 jdbc 二、面试题 1&#xff09;springmvc的作用 ​编辑 2&#x…

jQuery Ajax中dataType 和 content-type 参数的作用详解

jQuery Ajax中dataType与contentType参数解析 一、核心概念对比 参数作用对象数据类型默认值dataType响应数据预期接收的数据格式jQuery自动判断&#xff08;根据响应头MIME类型&#xff09;contentType请求数据发送数据的编码格式application/x-www-form-urlencoded 二、da…

几款常用的虚拟串口模拟器

几款常用的虚拟串口模拟器&#xff08;Virtual Serial Port Emulator&#xff09;&#xff0c;适用于 Windows 系统&#xff0c;可用于开发和调试串口通信应用&#xff1a; 1. com0com (开源免费) 特点&#xff1a; 完全开源免费&#xff0c;无功能限制。 可创建多个虚拟串口…

LLM笔记(六)线性代数

公式速查表 1. 向量与矩阵&#xff1a;表示、转换与知识存储的基础 向量表示 (Vectors): 语义的载体 在LLM中&#xff0c;向量 x ∈ R d \mathbf{x}\in\mathbb{R}^d x∈Rd 是信息的基本单元&#xff0c;承载着丰富的语义信息&#xff1a; 词嵌入向量 (Word Embeddings)&am…