Nodejsでヘッドレスブラウザを使ってオーディオを大量にダウンロードします.


背景
本来はAプラットフォームで本を聞きましたが、後の章に行くと、Bプラットフォームに行くしかないです.操作が煩雑で、体験が極めて悪いです.キャッシュはまだサポートされていません.流量がとても高いです.だから、オーディオを手動でダウンロードするしかないです.
需要
オーディオをダウンロードする操作は以下の通りです.
  • はリストページに入り、スクロールローディングが必要かもしれません.
  • は再生ページに入り、新しいタブを開いて、「再生ボタン」をクリックします.
  • 発信者のツールを開けて、audioタグを見つけて、「再生ボタン」をクリックしないとaudioタグが出ません.
  • 新しいタブにリンクをコピーして
  • を開きます.
  • ブラウザで持っている機能をダウンロードするには、
  • を注文する必要があります.
  • ダウンロード完了待ちです.
  • 別のタブに行ってオーディオの名前をコピーします.
  • はダウンロードしたコンテンツのフォルダに入り、名前を修正します.そうでなければ、全部名前です.区別ができません.
    この過程はまだ煩雑です.五六個をダウンロードしてからはもうつらいです.二百余りの章があります.
    実現する
    まず頭がないブラウザを思い出しました.その後、断続的に解決しました.具体的なオーディオアドレスは漏らしません.大同小異です.
    const puppeteer = require("puppeteer");
    const axios = require("axios");
    const querystring = require("querystring");
    const fs = require("fs");
    puppeteerは、「ヘッダなしブラウザ」として理解され、コードの形でヒューマン・マシン・インタラクションを実行することができる.日本語文書:http://www.puppeteerjs.com/#?...
    (async () => {
      const audioInfoList = [];
      const [
        reqUrl,
        search,
      ] = "             ".split(
        "?"
      );
    「改ページでリスト情報を取得するインターフェースアドレス」は、開発者ツールを使って入手したもので、できるだけ人機相互作用のシミュレーションを減らすことができます.そうでなければ、ここでマウスをスクロールさせて、アップロードをトリガします.
      let params = Object.assign({}, querystring.parse(search), {
        begin: 20,
        count: 10,
      });
    
    パラメータの置換
      const audioRsp = await axios.post(
        reqUrl + "?" + querystring.stringify(params)
      );
    
      const audioInfoList = audioRsp.data.appmsg_list.map((item) => ({
        name: item.title,
        url: item.link,
      }));
    ajaxリクエストを開始し、オーディオの名前とオーディオ再生ページのアドレスを記録します.
      for (let i = 0; i < audioInfoList.length; i++) {
        const audioItem = audioInfoList[i];
        try {
          const browser = await puppeteer.launch();
    
          const page = await browser.newPage({});
          await page.goto(audioItem.url, {
            waitUntil: "networkidle0",
          });
  • ブラウザ
  • を作成します.
  • タグページを作成します.
  • はオーディオ再生ページ
       page.waitForSelector(".audio_card_switch");
       await page.click(".audio_card_switch");
    に遷移し、.audio_card_switchが代表する「再生ボタン」が出現するのを待っています.
  •       const downloadSrc = await page.evaluate(() => {
            return document.querySelector("audio").src;
          });
          const audioContent = await axios.get(downloadSrc, {
            responseType: "arraybuffer",
          });
          fs.writeFileSync(`download/${audioItem.name}.mp3`, audioContent.data);
          console.log(
            `${i}/${audioInfoList.length - 1}  ${audioItem.name} : ${downloadSrc}`
          );
          await browser.close();
        } catch (error) {
          console.log(
            "    :" + i + " " + audioItem.name + "  " + audioItem.url
          );
        }
      }
    
  • は、オーディオアドレス
  • を取得する.
  • ajax要求によってオーディオコンテンツを取得するには、 responseType: "arraybuffer",が必要です.そうでないと、オーディオが再生できません.「このファイルは再生できません.ファイルタイプがサポートされていないため、ファイルの拡張子が不正またはファイルが破損している可能性があります.0 xc 00 d 36 c 4」のエラー
  • .
  • はオーディオファイルをローカルに格納します.
  • ダウンロード for (let i = 0; i < audioInfoList.length; i++) {、ダウンロードし終わったら次のページをダウンロードします.このように一度に現在のページのオーディオをダウンロードし終わります.これは一度に複数の audioInfoList.forEach(async (audioItem, audioIndex) => {をダウンロードするよりいいです.これは「資源」を食べます.ダウンロード順序も乱れています.ダウンロード失敗の確率が高いです.出現したら、どの問題が発生したのか、ディレクトリの中にあるのはオーディオではありません.
    0 xc 00 d 36 fa
    オーディオデバイスが見つかりません.イヤホンやスピーカーが接続されていることを確認してください.詳細については、デバイス内で「オーディオ機器の管理」を検索してください.
    このエラーをダウンロードのオーディオファイルとして扱わないでください.問題があります.