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

[复制链接]
发表于 2025-9-18 11:45:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
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 剖析和数据处理惩罚。以下是详细实现步调和示例代码:
一、常用工具


  • HTTP 哀求库

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

  • HTML 剖析

    • cheerio:类似 jQuery 的 DOM 利用库
    • jsdom:完备的 DOM 实现

  • 其他工具

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

二、静态页面抓取示例

  1. const axios = require('axios');
  2. const cheerio = require('cheerio');
  3. const fs = require('fs');
  4. async function fetchData(url) {
  5.   try {
  6.     const { data } = await axios.get(url);
  7.     const $ = cheerio.load(data);
  8.    
  9.     const results = [];
  10.     $('.product-item').each((i, element) => {
  11.       results.push({
  12.         name: $(element).find('.name').text().trim(),
  13.         price: $(element).find('.price').text().trim(),
  14.         link: $(element).find('a').attr('href')
  15.       });
  16.     });
  17.     fs.writeFileSync('products.json', JSON.stringify(results, null, 2));
  18.     console.log('数据抓取完成');
  19.   } catch (error) {
  20.     console.error('抓取失败:', error.message);
  21.   }
  22. }
  23. // 使用示例
  24. fetchData('https://example.com/products');
复制代码
三、动态页面抓取(利用 Puppeteer)

  1. const puppeteer = require('puppeteer');
  2. async function dynamicScraping(url) {
  3.   const browser = await puppeteer.launch();
  4.   const page = await browser.newPage();
  5.   
  6.   await page.goto(url, { waitUntil: 'networkidle2' });
  7.   
  8.   // 执行页面内 JavaScript
  9.   const data = await page.evaluate(() => {
  10.     return Array.from(document.querySelectorAll('.user-card'))
  11.       .map(card => ({
  12.         username: card.querySelector('.username').innerText,
  13.         bio: card.querySelector('.bio').innerText
  14.       }));
  15.   });
  16.   await browser.close();
  17.   return data;
  18. }
  19. // 使用示例
  20. dynamicScraping('https://example.com/users')
  21.   .then(data => console.log(data))
  22.   .catch(console.error);
复制代码
四、高级本领


  • 处理惩罚分页
  1. async function paginatedScraping(baseUrl, totalPages) {
  2.   const results = [];
  3.   
  4.   for (let page = 1; page <= totalPages; page++) {
  5.     const url = `${baseUrl}?page=${page}`;
  6.     const data = await fetchData(url);
  7.     results.push(...data);
  8.     await new Promise(resolve => setTimeout(resolve, 2000)); // 延迟防止封禁
  9.   }
  10.   
  11.   return results;
  12. }
复制代码

  • 并发控制
  1. const pLimit = require('p-limit');
  2. const limit = pLimit(3); // 最大并发数
  3. async function concurrentScraping(urls) {
  4.   const promises = urls.map(url =>
  5.     limit(() => fetchData(url))
  6.   );
  7.   return Promise.all(promises);
  8. }
复制代码

  • 代理设置
  1. const axiosInstance = axios.create({
  2.   proxy: {
  3.     host: 'proxy-server',
  4.     port: 8080,
  5.     auth: {
  6.       username: 'your_user',
  7.       password: 'your_pass'
  8.     }
  9.   }
  10. });
复制代码
五、数据存储选项


  • JSON 文件
  1. fs.writeFileSync('data.json', JSON.stringify(data));
复制代码

  • CSV 文件
  1. const createCsvWriter = require('csv-writer').createObjectCsvWriter;
  2. const csvWriter = createCsvWriter({
  3.   path: 'data.csv',
  4.   header: [
  5.     {id: 'name', title: 'NAME'},
  6.     {id: 'price', title: 'PRICE'}
  7.   ]
  8. });
  9. csvWriter.writeRecords(data);
复制代码

  • 数据库存储(MongoDB 示例)
  1. const mongoose = require('mongoose');
  2. const productSchema = new mongoose.Schema({
  3.   name: String,
  4.   price: Number,
  5.   link: String
  6. });
  7. const Product = mongoose.model('Product', productSchema);
  8. async function saveToDB(data) {
  9.   await mongoose.connect('mongodb://localhost:27017/scraping');
  10.   await Product.insertMany(data);
  11.   await mongoose.disconnect();
  12. }
复制代码
六、反爬虫对策


  • 设置公道的哀求头
  1. headers: {
  2.   'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
  3.   'Accept-Language': 'en-US,en;q=0.9'
  4. }
复制代码

  • 利用随机耽误
  1. function randomDelay(min, max) {
  2.   return new Promise(resolve =>
  3.     setTimeout(resolve, Math.random() * (max - min) + min)
  4.   );
  5. }
复制代码

  • 处理惩罚 Cookie
  1. const jar = new tough.CookieJar();
  2. axios.get(url, {
  3.   jar: jar,
  4.   withCredentials: true
  5. });
复制代码
七、错误处理惩罚最佳实践

  1. async function robustScraping(url, retries = 3) {
  2.   for (let i = 0; i < retries; i++) {
  3.     try {
  4.       return await fetchData(url);
  5.     } catch (error) {
  6.       if (i === retries - 1) throw error;
  7.       await new Promise(resolve => setTimeout(resolve, 5000 * (i + 1)));
  8.     }
  9.   }
  10. }
复制代码
留意事项


  • 服从 robots.txt 规则
  • 恭敬网站的服务条款
  • 控制哀求频率(发起 2-5 秒/哀求)
  • 处理惩罚敏感数据需符合 GDPR 等法规
  • 利用 try/catch 处理惩罚网络错误
  • 定期查抄选择器是否有用
根据详细需求可以组合这些技能,简单的静态页面利用 cheerio + axios 即可,复杂场景(SPA、必要登录)则必要 puppeteer。对于大规模抓取发起利用分布式架构(Redis 队列 + 多 Worker)。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表