簡體   English   中英

如何使用 node-fetch 下載文件

[英]How to download files with node-fetch

我需要幫助在 nodejs 中實現文件下載器。

所以我需要從服務器下載超過 25'000 個文件。 我正在使用node-fetch但我不完全知道如何實現這一點。 我嘗試使用Promise.allSettled()但我還需要一種方法來限制對服務器的並發請求數量,否則我會受到速率限制。

到目前為止,這是我的代碼:

const fetch = require('node-fetch')

async function main () {
  const urls = [
    'https://www.example.com/foo.png',
    'https://www.example.com/bar.gif',
    'https://www.example.com/baz.jpg',
    ... many more (~25k)
  ]

  // how to save each file on the machine with same file name and extension?
  // how to limit the amount of concurrent requests to the server?
  const files = await Promise.allSettled(
    urls.map((url) => fetch(url))
  )
}

main()

所以我的問題是:

  • 如何限制對服務器的並發請求量? 這可以使用帶有node-fetch的自定義 https 代理並將maxSockets設置為 10 來解決嗎?
  • 我如何檢查文件是否存在於服務器上,如果存在,然后以相同的文件名和擴展名將其下載到我的機器上?

如果有人可以展示一個小示例代碼我將如何實現此類功能,那將非常有幫助。

提前致謝。

要控制一次同時運行的請求數量,您可以使用以下三個選項中的任何一個:

這里mapConcurrent()這里pMap() :它們讓你迭代一個數組,向主機發送請求,但管理事物,以便你在決定 N 的值的同時只有 N 個請求在運行。

rateLimitMap() here :讓您管理每秒發送的請求數。

這可以使用帶有節點獲取的自定義 https 代理並將 maxSockets 設置為 10 來解決嗎?

我不知道使用自定義 https 代理的任何解決方案。

我如何檢查文件是否存在於服務器上,如果存在,然后以相同的文件名和擴展名將其下載到我的機器上?

您不能直接訪問遠程 http 服務器的文件系統。 因此,您所能做的就是對特定資源(url)發出 http 請求,並檢查 http 響應以查看它是否返回數據或返回某種 Z80791B3AE7002CB88C246876D9FAA8F8 錯誤,例如 a04

至於文件名和擴展名,這完全取決於您是否已經知道要請求什么以及服務器是否支持作為 URL 的一部分,或者服務器是否在 http Z099FB995346DBF31C7E49F46E 中向您返回該信息。 如果您請求特定的文件名和擴展名,那么您只需創建一個具有該名稱和擴展名的文件,並將 http 響應數據保存到本地驅動器上的該文件。

至於編碼示例, node-fetch()的文檔在此處顯示了使用流將數據下載到文件的示例: https://www.npmjs.com/package/node-fetch#streams

import {createWriteStream} from 'fs';
import {pipeline} from 'stream';
import {promisify} from 'util'
import fetch from 'node-fetch';

const streamPipeline = promisify(pipeline);

const testUrl = 'https://github.githubassets.com/images/modules/logos_page/Octocat.png';
const response = await fetch(testUrl);

if (!response.ok) throw new Error(`unexpected response ${response.statusText}`);

await streamPipeline(response.body, createWriteStream('./octocat.png'));

就個人而言,我不會使用node-fetch ,因為它的設計中心是模仿 node 的瀏覽器實現,它不像為 nodejs 明確構建的類似庫那樣友好的 API 設計。 我使用got()這里還列出了其他幾個不錯的庫。 你可以選擇你最喜歡的。

下面是一個使用got()庫的代碼示例

import {promisify} from 'node:util';
import stream from 'node:stream';
import fs from 'node:fs';
import got from 'got';

const pipeline = promisify(stream.pipeline);

await pipeline(
    got.stream('https://sindresorhus.com'),
    fs.createWriteStream('index.html')
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM