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.pswp.cn/news/906409.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906409.shtml
英文地址,請注明出處:http://en.pswp.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…