2025年7月2日 星期三

[Javascript]國立公共資訊圖書館的電子書服務平台進行複製標韱

 上篇:[ 國立公共資訊圖書館的電子書服務平台進行查詢所有符合的書目]



(1)先登入帳號1,將該帳號已標韱的書目產生"加入我的標韱"url


(async function () {

    const allUrls = [];

    const baseApi = "https://ebook.nlpi.edu.tw/personal/MyTagDetail";

    const tagName = "閱讀雲端-低年級";


    for (let start = 1; start <= 2; start++) {

        const url = `${baseApi}?tagName=${encodeURIComponent(tagName)}&start=${start}&limit=100&ajaxQuery=Y`;


        try {

            const response = await fetch(url);

            if (!response.ok) throw new Error(`API 錯誤:${response.status}`);

            const json = await response.json();


            if (Array.isArray(json.data)) {

                json.data.forEach(item => {

                    if (item.sid) {

                        const link = `https://ebook.nlpi.edu.tw/bookdetail/${item.sid}/booktag.add?tagName=${tagName}`;

                        allUrls.push(link);

                    }

                });

            }

        } catch (error) {

            console.error(`處理 start=${start} 時發生錯誤:`, error);

        }

    }


    // 將結果轉為純文字並下載

    const blob = new Blob([allUrls.join('\n')], { type: 'text/plain;charset=utf-8' });

    const downloadUrl = URL.createObjectURL(blob);

    const a = document.createElement('a');

    a.href = downloadUrl;

    a.download = 'booktag_links.txt';

    document.body.appendChild(a);

    a.click();

    document.body.removeChild(a);

    URL.revokeObjectURL(downloadUrl);

})();


(2)改登入帳號2,將產生連結進行寫入

(async function () {

    const urls = [

        "https://ebook.nlpi.edu.tw/bookdetail/1559/booktag.add?tagName=閱讀雲端-低年級",

        "https://ebook.nlpi.edu.tw/bookdetail/1463/booktag.add?tagName=閱讀雲端-低年級",

        "https://ebook.nlpi.edu.tw/bookdetail/953/booktag.add?tagName=閱讀雲端-低年級",

        "https://ebook.nlpi.edu.tw/bookdetail/1066/booktag.add?tagName=閱讀雲端-低年級",

        // ...(請將所有 URL 放入此陣列)

        "https://ebook.nlpi.edu.tw/bookdetail/11041/booktag.add?tagName=閱讀雲端-低年級"

    ];


    for (let i = 0; i < urls.length; i++) {

        try {

            const response = await fetch(urls[i], {

                method: 'GET',

                headers: {

                    'Content-Type': 'application/json'

                }

            });


            if (!response.ok) {

                console.error(`❌ 第 ${i + 1} 筆失敗:${response.status} - ${urls[i]}`);

                continue;

            }


            const result = await response.text(); // 或 .json() 視 API 回傳格式

            console.log(`✅ 第 ${i + 1} 筆成功:`, result);

        } catch (err) {

            console.error(`⚠️ 第 ${i + 1} 筆錯誤:`, err);

        }

    }

})();


2025年7月1日 星期二

[Javascript]飛閱雲端 中文圖書認證列出所有的適讀年級的書目

彰化縣飛閱雲端的 中文圖書認證查詢功能太過於陽春,無法只列出特定適讀年級的書目

 飛關雲端的網站後先登入,然後使用下面JavaScript,按F12 進入開發者工具的「主控台」,把下面指令貼上後,可以把1 - 251 頁的資料都爬過一次,並將適讀年級為「低年級」的資料轉成檔案下載下來。



(async () => {

  const result = [];

  const totalPage = 251; //總頁數,請自已輸入

  const targetGradeLevel = "低年級"; //要查詢的適讀年級,請自已輸入

  for (let page = 1; page <= totalPage; page++) {

    const url = `https://read.chc.edu.tw/item6/menu1.php?topage=${page}`;


    try {

      const response = await fetch(url);

      const htmlText = await response.text();


      const parser = new DOMParser();

      const doc = parser.parseFromString(htmlText, 'text/html');


      // 找出所有 table,搜尋包含指定表頭的那一個

      const tables = doc.querySelectorAll('table');

      let targetTable = null;


      for (const table of tables) {

        const headerRow = table.querySelector('tr[bgcolor="#CCCCCC"].font4');

    //console.error(headerRow);

        if (headerRow) {

          const headers = Array.from(headerRow.querySelectorAll('td')).map(td => td.textContent.trim());

  console.log(headers)

          if (

            headers.includes('書名') &&

            headers.includes('ISBN') &&

            headers.includes('書目類別') &&

            headers.includes('適讀年段') &&

            headers.includes('認證人數\n                  (通過/已認證)')

          ) {

            targetTable = table;

            break;

          }

        }

      }


      if (!targetTable){

        continue;

  }


      const rows = targetTable.querySelectorAll('tr');

      for (let i = 1; i < rows.length; i++) {

        const cells = rows[i].querySelectorAll('td');

        if (cells.length >= 4) {

          const title = cells[0].textContent.trim();

          const gradeLevel = cells[3].textContent.trim();

          if (gradeLevel.includes(targetGradeLevel)) {

            result.push(title);

          }

        }

      }

    } catch (err) {

      console.error(`第 ${page} 頁失敗:`, err);

    }

  }


  console.log('所有適讀年段為「'+targetGradeLevel+'」的書名如下:');

  console.log(result);

  

  console.log("轉成 CSV 字串");

  // 轉成 CSV 字串

  let csvContent = '書名\n';

  result.forEach(t => {

    const escapedTitle = t;

    csvContent += `"${escapedTitle}"\n`;

  });


  // 建立下載連結並觸發下載

  const blob = new Blob([csvContent], { type: 'text/csv;charset=big5;' });

  const urlObject = URL.createObjectURL(blob);

  const link = document.createElement('a');

  link.href = urlObject;

  link.setAttribute('download', targetGradeLevel + '書籍清單.txt');

  document.body.appendChild(link);

  link.click();

  document.body.removeChild(link);  

  

})();


====以下改為增加取得 ISBN==========


(async () => {


  const result = [];


  const totalPage = 252; //總頁數,請自已輸入


  const targetGradeLevel = "低年級"; //要查詢的適讀年級,請自已輸入


  for (let page = 1; page <= totalPage; page++) {


    const url = `https://read.chc.edu.tw/item6/menu1.php?topage=${page}`;




    try {


      const response = await fetch(url);


      const htmlText = await response.text();




      const parser = new DOMParser();


      const doc = parser.parseFromString(htmlText, 'text/html');




      // 找出所有 table,搜尋包含指定表頭的那一個


      const tables = doc.querySelectorAll('table');


      let targetTable = null;




      for (const table of tables) {


        const headerRow = table.querySelector('tr[bgcolor="#CCCCCC"].font4');



    //console.error(headerRow);


        if (headerRow) {


          const headers = Array.from(headerRow.querySelectorAll('td')).map(td => td.textContent.trim());


  console.log(headers)


          if (


            headers.includes('書名') &&


            headers.includes('ISBN') &&


            headers.includes('書目類別') &&


            headers.includes('適讀年段') &&


            headers.includes('認證人數\n                  (通過/已認證)')


          ) {


            targetTable = table;


            break;


          }


        }


      }




      if (!targetTable){


        continue;


  }




      const rows = targetTable.querySelectorAll('tr');


      for (let i = 1; i < rows.length; i++) {


        const cells = rows[i].querySelectorAll('td');


        if (cells.length >= 4) {


          const title = cells[0].textContent.trim();

          const ISBN = cells[1].textContent.trim();


          const gradeLevel = cells[3].textContent.trim();


          const goTest = cells[5].textContent.trim();

          //console.log(title,ISBN,goTest);

          if (gradeLevel.includes(targetGradeLevel) && goTest.includes("我要認證")) {


            result.push(ISBN + "," + title);


          }


        }


      }


    } catch (err) {


      console.error(`第 ${page} 頁失敗:`, err);


    }


  }




  console.log('所有適讀年段為「'+targetGradeLevel+'」的書名如下:');


  console.log(result);


  


  console.log("轉成 CSV 字串");


  // 轉成 CSV 字串


  let csvContent = 'ISBN,書名\n';


  result.forEach(t => {


    const escapedTitle = t;


    csvContent += `"${escapedTitle}"\n`;


  });




  // 建立下載連結並觸發下載


  const blob = new Blob([csvContent], { type: 'text/csv;charset=big5;' });


  const urlObject = URL.createObjectURL(blob);


  const link = document.createElement('a');


  link.href = urlObject;


  link.setAttribute('download', targetGradeLevel + '書籍清單.txt');


  document.body.appendChild(link);


  link.click();


  document.body.removeChild(link);  


  


})();