ガンバライジングはまったくやれていないのですが(汗)、

ツール開発はコツコツ続けております。

ディエンドです。

 

とりあえず、GAS(Google Apps Script)でなんとか作ってやろうと始めたのですが、

なんか勢いついちゃって、ほぼほぼ完成しちゃいました。

ググるキーワードとしては、

  • Google Apps Script
  • Googleスプレッドシート
  • Webスクレイピング
  • Cheerio
  • Selector

あたりです。

で、いくつかの県を試してみて上手くいってそうだったので、

これは、47都道府県全部一気にやってみよう!!

ということで、プログラムを実行したのですが、、、、、、、

 

 

え?え?タイムアウトって何?

 

で、またググる(爆)

どうも、GASは6分間の実行時間制限があるらしい。

実行結果を見てみると、北海道からスタートして、神奈川県の途中まで出力できていました。

つまり、13都道府県はコンプリート、14県目でタイムアウトってな感じ。

これは、分割起動しないとダメっぽい。

 

まぁ、とりあえず、ここまでのプログラムを記載しておきます。

 

 

//
// これがMAINの関数
// 
function myFunction() {
  const NUM_OF_PREFECTURE = 47;

  // Googleスプレッドシートに書き込む準備
  let targetRow = 1;
  const sheet = prepareSpreadSheet(targetRow++);

  for (let pref = 1; pref <= NUM_OF_PREFECTURE; pref++) { // 都道府県分繰り返す
    targetRow = outputOnePrefecture(sheet, targetRow, pref);
  }
}

//
// 出力するスプレッドシートの初期化
// 引数:initRow = 行番号の初期値
// 戻値:sheet   = シートオブジェクト
//
function prepareSpreadSheet(initRow) {
  const TARGET_SHEET_NAME = 'シート2';

  const spreadSheet = SpreadsheetApp.openById("スプレッドシートIDを指定");
  const sheet = spreadSheet.getSheetByName(TARGET_SHEET_NAME)
  sheet.clearContents(); // 出力シートをクリア

  const title = [["店名", "住所"]];
  sheet.getRange(getOutputRange(initRow)).setValues(title); //タイトルを設定

  return sheet;
}

//
// 出力するスプレッドシートのRANGE文字列取得
//
function getOutputRange(row) {
  const OUTPUT_RANGE_FORMAT = "A%d:B%d";
  return Utilities.formatString(OUTPUT_RANGE_FORMAT, row, row);
}

//
// 1つの都道府県の店舗データを出力する
// 引数:sheet = 出力シート
//      row   = 出力開始行
//      prefIndex = 都道府県番号
// 戻値:row   = 次の出力行
//
function outputOnePrefecture(sheet, row, prefIndex) {
  const URL_FORMAT = "https://www.ganbarizing.com/shop/list.php?pref=%02d&p=%d";

  let page = 1;
  do {
    let url = Utilities.formatString(URL_FORMAT, prefIndex, page);
    let res = UrlFetchApp.fetch(url).getContentText();    
    let $ = Cheerio.load(res);
    let $data = $('table.resultTb tbody tr td');
    
    //
    // 終了判定:HITする店舗がなくなったら終了
    //
    let isEmpty = ($($data[0]).text() == "検索条件にHITする店舗がありません。");
    if (isEmpty) break;

    //
    // 店舗がある場合は、シートへ出力する
    //
    let shop = ["", ""];
    $data.each(function(index, element){
      if (index % 3 == 0) { // 店舗名
        shop[0] = $(element).text().slice(0, -3);
      } else if (index % 3 == 1) { // 住所
        shop[1] = $(element).text();
        sheet.getRange(getOutputRange(row++)).setValues([shop]);
      }
    })

    Utilities.sleep(2000); //連続でアクセスしたら迷惑なので、2秒間隔にする
  } while(++page <= 30); //暫定処理。最悪30ページ分ループしたら終了。もし30ページ以上の都道府県が出てきたら再考要

  Logger.log(Utilities.formatString("process:%02d, num_page=%d", prefIndex, page-1));

  return row;
}

 

 

つづく。