図書館の所蔵、貸出、予約情報をGASでスクレイピングしてみる

解決したいこと

  • 中央区立図書館の本の検索を簡単にしたい
  • 一度検索したものの予約画面にすぐに行きたい
  • 検索結果の本の予約状況とかを簡単にみたい

結果

キーワード列に検索ワードを入力し、スクリプトを実行すると、その検索結果で出てきた書籍の書名、予約ページのURL、所蔵数、貸出数、予約数を取得した。

プログラム

// ここでスクレイピングするべきキーワードを取得し、search_bookにキーワードを渡す。
function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();
  // 最終行までチェックする。
  for (var i = 1; i <= sheet.getLastRow(); i++) {
    var keyword = sheet.getRange(i, 1).getValue();
    // キーワードが入っていて、書名が入っていない場合はそのキーワードでスクレイピングする。
    if (keyword.length > 0 && sheet.getRange(i, 2).getValue().length == 0) {
      search_book(i, keyword, sheet);
    }
  }
}

// 受け取ったキーワードを元に検索して検索結果の書名とURLのリストをスプレッドシートに記入する。URLをcrawl_detailに渡して所蔵数、貸出数、予約数を取得する。
function search_book(id, keyword, sheet) {
  var base_url = "https://www.library.city.chuo.tokyo.jp/"
  var arr = fetch(base_url + "detailresult?10&target1=1&key1=" + keyword + "&item1=AB&comp1=3&cond=1&sort=1&genre&mater&mv=20&lib2&lib3&mater2&mater3&retresult=page%3DDETAIL%26comp1%3D3%26cond%3D1%26genre%3D%26item1%3DAB%26key1%3D" + keyword + "%26lib2%3D%26lib3%3D%26mater%3D%26mater2%3D%26mater3%3D%26mv%3D20%26sort%3D1%26target1%3D1%26");
  for (var i = 0; i < arr.length; i++) {
    if (arr[i].match(/.*<a href=.*?<\/a>/)) {
      var result_link = arr[i].match(/.*<a href=(.*?)<\/a>/)[1]
      // 本の詳細ページのリンクのみ処理する。
      if (result_link.indexOf(keyword) >= 0 && result_link.indexOf("bookdetail") >= 0) {
        Utilities.sleep(1500);
        // 取得したリンクにはセッションIDみたいなものが入っていたので削除、"&"が"&"になっていたので"amp;"を削除する。
        var detail_link = arr[i].match(/.*<a href="(.*?)".*/)[1].replace(/;.*?\?/, "?").replace(/amp;/g,"")
        // 取得したリンクは"./~~~"となっているので最初の2文字を消してルートURLにつなげる。
        sheet.getRange(id, 3).setValue(base_url + detail_link.slice(2));
        // タグ部分、空白を削除、こちらも"&"が"&"になってしまうので"amp;"を削除する。
        sheet.getRange(id, 2).setValue(arr[i].replace(/<("[^"]*"|'[^']*'|[^'">])*>/,"").replace(/<.*?>/g, "").replace(/\s/g,"").replace(/amp;/g,""));
        // 詳細画面をスクレイピング!
        book_num = crawl_detail(base_url + detail_link.slice(2));
        for (j = 0; j < book_num.length; j++ ) {
          sheet.getRange(id, j + 4).setValue(book_num[j]);
        }
        id += 1;
      }
    }
  }
}

// HTTPリクエストのレスポンスを1行ずつリストにして返す。
function fetch(url) {
  var response = UrlFetchApp.fetch(url);
  var content = response.getContentText("UTF-8");
  return content.split("\n");
}

// 本の詳細画面からその本の所蔵数、貸出数、予約数をリストで返す。
function crawl_detail(url) {
  book_num = [];
  var detail_arr = fetch(url);
  for (var i = 0; i < detail_arr.length; i++) {
    if (detail_arr[i].match(/.*?class="colon".*?/)) {
      if (detail_arr[i].match(/.*所蔵数.*/)) {
        book_num.push(detail_arr[i].match(/.*([0-9]+).*/)[1]);
      } else if (detail_arr[i].match(/.*貸出数.*/)) {
        book_num.push(detail_arr[i].match(/.*([0-9]+).*/)[1]);
      } else if (detail_arr[i].match(/.*予約数.*/)) {
        book_num.push(detail_arr[i].match(/.*([0-9]+).*/)[1]);
      }
    }
  }
  return book_num;
}

詰まったところ

実際にWEBページを遷移した時とスクレイピングでリンクを取得したときのURLが異なっていた。スクレイピングで取得したリンクを加工して正しいリンクを取得するように修正した。

コメント

タイトルとURLをコピーしました