揮発性のメモ2

最近知った知識を さも昔から知ってた風にメモ書きしていく

ラブラッドの献血記録を取得する

ラブラッドの「献血記録の確認」画面から、検査結果を取得する。
次のコードを全部コピーして、DevToolsの「コンソール」にペーストすると
CSVファイルとして全データをダウンロードする。

操作は1秒間隔でおこなわれるので、人間がやるよりもゆっくりで 機械にやさしい

/**
 * ラブラッドの「献血記録の確認」画面から、検査結果をスクレイピングする
 *
 * 「献血記録の確認」を開いた状態で、DevToolsでこれを全部コピペすると
 * 全データがCSVファイルとしてダウンロードされる(UTF-8)
 */



/**
 * ミリ秒スリープ
 */
const mssleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

/**
 * テーブルからデータを取得し、配列を返す
 * @param {number} n -  列指定(1~3)
 * @returns {string[]}  その列のデータ
 */
function getcsvfromtable(n){
    const table = $("div.mod-result-table");
    let data = [];

    for(let i=0; i<3; i++){
        const retsu = table.eq(i).find("li:nth-child(" + n + ")");

        /* 日付取得 */
        if(i===0){
            const date = retsu.eq(0).find("div").eq(1).text();
            data.push(date);
        }
        /* データ取得 */
        for(let x=1; x<retsu.length; x++){
            data.push(retsu.eq(x).text());
        }
    }

    return data;
}

/**
 * テーブルからCSV用ヘッダを取得し、配列を返す
 * @returns {string[]}  ヘッダ文字列の配列
 */
function getcsvtitle(){
    const table = $("div.mod-result-table");
    let data = ["日時"];

    for(let i=0; i<3; i++){
        const retsu = table.eq(i).find("div.mod-result-table__label");

        for(let x=0; x<retsu.length; x++){
            data.push( $.trim(retsu.eq(x).text()) );
        }
    }

    return data;
}


/**
 * 配列をCSV文字列にする
 * @param {string[][]} array - 2次元配列(各行は文字列の配列)
 * @returns {string} CSV形式の文字列
 */
function array2csv(array) {
    return array.map(row => row.join(",") + "\n").join("");
}

/**
 * ファイルとしてダウンロードさせる
 * @param fileName
 * @param content
 */
function downloadAsFile( fileName, content ){
    const blob = new Blob([content], {type: 'text/csv'});
    const url = window.URL || window.webkitURL;
    const blobURL = url.createObjectURL(blob);

    const a = document.createElement('a');
    a.download = fileName;
    a.href = blobURL;
    a.click();
}



/*--------------------------------------*/
/* メイン開始                           */
/*--------------------------------------*/

let csv = [];
/* 表題を配列に保存する */
csv.push(getcsvtitle());

main: for(let counter=0; counter<33; counter++){ /* 保険でループ上限付ける */

    /* 画面に表示されている表を読んで配列に保存する */
    for(let n=3; n>0; n--){
        const data = getcsvfromtable(n);
        if(data[0]==="") break main; /* データなしに到達 */
        if(csv.at(-1)[0]===data[0]) break main; /* 最後のデータに到達 */

        console.log(data);
        csv.push(data);
    }

    /* 前に戻るボタンが押せないときは もう過去が無いので終了する */
    const prevbutton = $("div.is-prev.slick-arrow");
    if(prevbutton.attr("aria-disabled")!=="false") break;

    /* 前に戻るボタンを3回押して、表を再表示する */
    for(let i=0; i<3; i++){
        prevbutton.click();
        await mssleep(1000);
    }
    $('input[type="submit"][value="変更する"]').click();
    await mssleep(1000);
}

let text = array2csv(csv); /* 配列をCSV文字列に変換 */
downloadAsFile("blood.csv", text); /* ファイルとしてダウンロード */