Cómo usar Nodejs para descargar el video de la estación B con un clic

Cómo descargar video de la estación B con un clic

Para descargar fácilmente el video de la estación B, escribí una pequeña herramienta con Nodejs, y usé ibiliesta biblioteca para descargar al principio, pero debido al problema de no poder personalizar el directorio de descarga, era un inconveniente modificar , así que construí una rueda.

Dirección del almacén , estrella de bienvenida.

Características

  • Descargar trabajos individuales basados ​​en URL
  • Descarga todas las obras según la URL de la página de inicio del máster UP
  • Opción para descargar video o audio

Requisitos medioambientales

Para usar esta herramienta, necesita Node y npm, si no lo tiene, puede ir al sitio web oficial para descargarlo e instalarlo.

usar

Instalar:

npm i bilibili-save-nodejs
复制代码

Uso de herramientas de línea de comandos

bili-download
复制代码

Elija qué y cómo descargar según el menú de la línea de comandos

Arrastre de bienes privados: persecución de estrellas con un clic, descargue todos los videos de Jiu San :

bili-download -d
复制代码

Uso de la API de Node.js

Nombre de la función efecto
download descargar
downloadByVedioPath Descargar un solo trabajo basado en la URL del video
downloadByHomePath Descarga todas las obras según la página de inicio de la UP

Parámetros de la API

Nota: Los parámetros de las tres funciones están en forma de objetos.

descargar

nombre del parámetro Es necesario Rangos significado
descargaRango ['byAuthor','byVedio'] Según la URL de la página de inicio del autor o la URL de trabajo
tipo de descarga ['mp4','mp3'] Descargar video o audio
ruta de descarga ninguna URL de trabajo legal o URL de la página de inicio de UP
carpeta de descargas no ninguna La ruta completa al directorio de almacenamiento , el valor predeterminado se usa de forma predeterminada

Valores predeterminados del directorio:

  • /videoVideo: En una carpeta bajo el directorio raíz
  • /audioAudio: en una carpeta bajo el directorio raíz

manifestación:

const { download } = require("bilibili-download-nodejs");
download({
  downloadRange: "byAuthor",
  downloadType: "mp4",
  downloadPath: "https://space.bilibili.com/313580179",
})
  .then(() => console.log("下载成功"))
  .catch((e) => console.log("下载出错"));
复制代码

downloadByVedioPath & downloadByHomePath

参数名 是否必须 取值范围 含义
type ['mp4','mp3'] 下载视频音频
url 合法的作品 URL
folder 存储目录的完整路径

demo:

const { downloadByVedioPath, downloadByHomePath } = require("./download.js");
const path = require("path");

// 下载单个作品的视频
downloadByVedioPath({
  url: "https://www.bilibili.com/video/BV1AL4y1L7cg",
  type: "mp4",
  folder: path.join(__dirname, "/foo"),
})
  .then(() => console.log("下载成功"))
  .catch((e) => console.log("下载出错"));

// 下载UP主所有作品的音频
downloadByHomePath({
  url: "https://space.bilibili.com/313580179",
  type: "mp3",
  folder: path.join(__dirname, "/bar"),
})
  .then(() => console.log("下载成功"))
  .catch((e) => console.log("下载出错"));
复制代码

原理介绍

介绍完用法,简单介绍本项目的原理。

根据视频 URL 下载视频

根据 URL 获取 bvid

bvid 是现在 b 站视频的唯一标识,也是后续操作的必备参数。但为了方便使用,直接复制作品的 URL 更好理解和操作。

其实 bvid 就存在于 URL 之中,只需要做简单的字符串操作:

const urlList = url.split("/");
const bvid = urlList[urlList.length - 1].split("?")[0];
复制代码

根据 bvid 获取 cid 数组与作品标题

对于多 p 视频,仅通过 bvid 无法确定请求的是哪一 p 视频,此时 cid 起到了唯一标识视频的作用。通过浏览器抓包分析接口,可知获取 cid 的方法为:

const getCidByBvid = async (bvid) => {
  const res = await axios.get("https://api.bilibili.com/x/web-interface/view", {
    params: {
      bvid,
    },
  });
  return res.data.data.pages.map((item) => item.cid);
};
复制代码

该接口用于查询作品信息,因此获取作品标题的方法为:

const getTitleByBvid = async (bvid) => {
  const res = await axios.get("https://api.bilibili.com/x/web-interface/view", {
    params: {
      bvid,
    },
  });
  return res.data.data.title;
};
复制代码

根据 bvid 获取视频下载地址数组

  1. 首先,根据 bvid 获取 cid 数组
  2. 对于每个 cid,与 bvid 一起唯一标识了视频,进行请求
  3. 根据下载类型的不同(视频或音频),传入参数会不同。

参数含义:

  • fnval设为 16 时,音视频将会分离,此时可以达到只下载音频的目的
  • qn参数标识清晰度,对照如下
清晰度 字段取值
4K 120
1080p+ 112
1080p 80
720p 64
480p 32
360p 16

完整实现代码为:

const getDownloadPathById = async (bvid, type) => {
  const cidList = await getCidByBvid(bvid);
  const result = [];
  for (const cid of cidList) {
    const params = {
      bvid,
      cid,
      qn: 112,
    };
    if (type === "mp3") {
      params.fnval = 16;
    }
    const res = await axios.get("https://api.bilibili.com/x/player/playurl", {
      params,
    });
    result.push(
      type === "mp3"
        ? res.data.data.dash.audio[0].baseUrl
        : res.data.data.durl[0].url
    );
  }
  return result;
};
复制代码

根据下载地址下载资源

getDownloadPathById返回的是下载地址,但直接在浏览器打开会报错,这是因为 request header 必须带有 referer 字段。

通过抓包可知, referer 字段取值就是视频地址,因此:

const getRefererByBvid = (bvid) => `https://www.bilibili.com/video/${bvid}`;
复制代码

下载资源的思路是:

  • 检查目标文件是否存在,若存在不重复下载
  • 根据 bvid 获取 referer 字段
  • 请求资源
  • 写入文件

完整实现:

const downloadResource = async ({ url, referer, folder, title, type }) => {
  const target = path.join(folder, `${title}.${type}`);
  if (fs.existsSync(target)) {
    console.log(`视频 ${title} 已存在`);
    return Promise.resolve();
  }
  const res = await axios.get(url, {
    headers: {
      referer,
    },
    responseType: "stream",
  });
  console.log(`开始下载:${title}.${type}`);
  const writer = fs.createWriteStream(target);
  res.data.pipe(writer);
  return new Promise((resolve, reject) => {
    writer.on("finish", resolve);
    writer.on("error", reject);
  });
};
复制代码

Descargue el video de acuerdo con la URL de la página de inicio de UP

Obtener mediados de la URL de la página de inicio de UP

mid es el identificador único de cada usuario de la estación B. También para facilitar la comprensión y el uso, la interfaz expuesta utiliza la URL de la página de inicio de UP y realiza el procesamiento de cadenas para obtener el mid:

const getMidByUrl = (url) => {
  const reg = /space.bilibili.com\/(?<mid>\d+)/;
  return url.match(reg).groups?.mid;
};
复制代码

Obtenga la dirección de la página de inicio del video de acuerdo con el medio principal superior

De acuerdo con la captura de paquetes, se requieren tres parámetros para obtener información de la página de inicio:

  • medio: ID de cuenta
  • pd: número de videos por página
  • pn: número de página actual

Usando el número predeterminado de 30 por página, la operación para obtener la página de inicio se puede escribir como:

const getHomeUrl = (mid, currentPage) =>
  `https://api.bilibili.com/x/space/arc/search?mid=${mid}&ps=30&pn=${currentPage}`;
复制代码

Los datos devueltos se analizan mediante la captura de paquetes, y el resultado devuelto es data.list.vlistla información de video, en la que se puede obtener bvid, y el proceso de descarga posterior es el mismo que el anterior.

Referirse a

Supongo que te gusta

Origin juejin.im/post/7087973085097230349
Recomendado
Clasificación