2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ラジコのAPIから放送局を指定し土日のみの番組表をスプレッドシートにシート別に書きだす

Last updated at Posted at 2020-06-12

ディレクターの方よりある放送局の土日のみラジコの番組表がほしいと相談があったのでGASの勉強兼ねて実装してみました。
ラジコのAPI(v3)を調べてみると以下のような形でXMLが取得できるとのことでした。

http://radiko.jp/v3/program/station/date/日付/放送局名.xml

実際にできあがったコードが以下になります。
ちょっと無駄な記述もあるかもですがご容赦くださいませ。
こちらをGASのスクリプトエディタに貼り付け「実行」 -> 「関数を実行」 -> 「generate」を選択します。

Code.gs
// 開始日
const startDate = new Date('2020-05-01');
// 終了日
const endDate = new Date('2020-06-30');
// 放送局名
const broadcaster = 'FM_OKINAWA';

const week = {
  sunday   : 0,
  monday   : 1,
  tuesday  : 2,
  wednesday: 3,
  thursday : 4,
  friday   : 5,
  saturday : 6
};

const weekend = [week.sunday, week.saturday];

function normalizeSheetName(sheetName) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  sheet.setName(sheetName);
}

function createSheet(sheetName) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  ss.insertSheet(sheetName);
}

function deleteSheet(sheetName) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(sheetName);
  ss.deleteSheet(sheet);
}

function deleteOtherThanActiveSheet() {
 const activeSheet = SpreadsheetApp.getActiveSpreadsheet();
 const len = activeSheet.getNumSheets();

 activeSheet.moveActiveSheet(1);

 for (let i = len; 1 < i; i--) {
  const sheet = activeSheet.getSheets()[i-1];
  activeSheet.deleteSheet(sheet);
 }
}

function getWeekendArray(start, end) {
  const arr = [];
  const dt = new Date(start);

  while (dt <= end) {
    if (weekend.includes(dt.getDay())) {
      const year = dt.getFullYear();
      const month = ('0' + (dt.getMonth() + 1)).slice(-2);
      const day = ('0' + dt.getDate()).slice(-2);
      
      arr.push({ year, month, day });
    }
    dt.setDate(dt.getDate() + 1);
  }
  
  return arr;
}

function fetchUrl(url) {
  const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true });

  if (res.getResponseCode() !== 200) {
    return null;
  }
      
  return res;
}

function insert(str, index, value) {
  return str.substr(0, index) + value + str.substr(index);
}
    
function formatTime(start, end) {
  return `${insert(start, 2, ':')} 〜 ${insert(end, 2, ':')}`;
}

function getValues(prog) {
  return prog.map((entry) => {
    return [
      formatTime(entry.getAttribute("ftl").getValue(), entry.getAttribute("tol").getValue()),
      entry.getChildText('title'),
      entry.getChildText('pfm')
    ];
  });
}

function generate() {
  if (SpreadsheetApp.getActiveSpreadsheet().getNumSheets() > 1) {
    deleteOtherThanActiveSheet();
  }
  
  const sheetName = `Sheet_${Date.now ()}`;
  normalizeSheetName(sheetName);
  
  const weekendArr = getWeekendArray(startDate, endDate);
        
  weekendArr.forEach((weekend) => {
    const { year, month, day } = weekend; 
    const response = fetchUrl(`http://radiko.jp/v3/program/station/date/${year}${month}${day}/${broadcaster}.xml`);

    if (response) {
      const xml = XmlService.parse(response.getContentText());
      const root = xml.getRootElement();
      const values = getValues(root.getChildren("stations")[0].getChildren("station")[0].getChildren("progs")[0].getChildren('prog'));
      
      createSheet(`${year}/${month}/${day}`);
    
      const sheet = SpreadsheetApp.getActiveSheet();
      sheet.getRange(1, 1, values.length, 3).setValues(values);
    }
  });
  
  deleteSheet(sheetName);
}

添付のようにシート別に番組表が書き出せました。
Jun-12-2020 18-29-18.gif

同じ境遇の方はあまりいないとは思うのですが、この記事が誰かのお役に立てれば幸いです。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?