当前位置: 首页 > news >正文

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)。

相关文章:

  • BERT模型讲解
  • AI汽车时代的全面赋能者:德赛西威全栈能力再升级
  • 【Python】超全常用 conda 命令整理
  • C++中static关键字详解:不同情况下的使用方式
  • 浏览器节能机制导致Websocket断连的坑
  • CentOS 7 系统下安装 OpenSSL 1.0.2k 依赖问题的处理
  • [sklearn] 特征工程
  • 支付宝沙盒模式商家转账经常出现 响应异常: 解包错误
  • 嵌入式裸机模块——软定时器
  • 数据结构-堆
  • AWS之数据分析类产品
  • Mac 3大好用的复制粘贴管理工具对比
  • Android RxJava框架分析:它的执行流程是如何的?它的线程是如何切换的?如何自定义RxJava操作符?
  • 第十七节:图像梯度与边缘检测-Sobel 算子
  • Uskin阵列式三轴力触觉传感器:驱动机器人智能的触觉数据专家
  • 深入理解 Java 代理模式:从基础到实战​
  • MiM: Mask in Mask Self-SupervisedPre-Training for 3D Medical Image Analysis
  • Docker宿主机IP获取
  • 智慧工会服务平台建设方案Word(23页)
  • 机器学习-无量纲化与特征降维(一)
  • 公示!17个新职业、42个新工种亮相
  • 上海质子重离子医院二期项目启动,有望成为全世界最大粒子治疗中心
  • 纪录片《中国》原班人马打造,《船山先生》美学再升级
  • 家庭相册㉙在沪打拼25年,我理解了父母清晨去卖蜜饯的辛苦
  • 国家发改委:目前有的核电项目民间资本参股比例已经达到20%
  • 前瞻|美联储明晨“按兵不动”几无悬念:关税战阴霾下,会否释放降息信号