-
-
Save totoraj930/282bec347d471835aa8f99211a4acecb to your computer and use it in GitHub Desktop.
ニコ動のマイリストをマイリストページのRSSから取得するやつ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict" | |
const http = require("http"); | |
const fs = require("fs"); | |
const cheerio = require("cheerio"); | |
// コマンドの引数を受け取って処理 | |
if (process.argv.length < 3) { | |
console.log("マイリストIDを指定してください"); | |
} else { | |
var id = process.argv[2], | |
user_session = (process.argv[3])?process.argv[3]:""; | |
getMylistFromRss(id, user_session).then(function (result) { | |
var fileName = "mylist_" + id + ".json"; | |
console.log("タイトル: "+result.title); | |
console.log("アイテム数: "+result.item.length); | |
fs.writeFile( | |
fileName, | |
JSON.stringify(result, null, " ") | |
); | |
console.log("\"" + fileName + "\"に出力しました"); | |
}).catch(function (error) { | |
console.log(error); | |
}); | |
} | |
/** | |
* HTTPでヘッダーも含めて取得してPromiseで返す | |
* @param {Object} options - http.requestで使うオプション | |
* @return {Promise} | |
*/ | |
function getByHttp (options) { | |
return new Promise(function (resolve, reject) { | |
var req = http.request(options, function (res) { | |
res.setEncoding("utf8"); | |
var temp = ""; | |
if (res.statusCode < 200 || res.statusCode > 299) { | |
reject(new Error(res.statusCode)); | |
} | |
res.on("data", function (chunk) { | |
temp += chunk; | |
}); | |
res.on("end", function () { | |
resolve({ | |
headers: res.headers, | |
body: temp | |
}); | |
}); | |
}); | |
req.on("error", function (error) { | |
reject(error); | |
}); | |
req.end(); | |
}); | |
} | |
/** | |
* マイリストを取得してPromiseで返す | |
* @param {String} id - マイリストID | |
* @return {Promise} | |
*/ | |
function getMylistFromRss (id, user_session) { | |
return new Promise(function (resolve, reject) { | |
getByHttp({ | |
hostname: "www.nicovideo.jp", | |
path: "/mylist/"+id+"?rss=2.0", | |
port: 80, | |
method: "GET", | |
headers: { | |
"Cookie": "user_session="+user_session+";" | |
} | |
}).then(function (result) { | |
resolve(getMylistData(result.body)); | |
}).catch(function (error) { | |
reject(error); | |
}); | |
}); | |
} | |
/** | |
* RSSからマイリストデータを生成 | |
* @param {String} xml - RSSの文字列 | |
* @return {Object} | |
*/ | |
function getMylistData (xml) { | |
var $ = cheerio.load(xml, { xmlMode: true}), | |
ret = { | |
id: "", | |
title: "", | |
description: "", | |
creator: "", | |
item: [] | |
}; | |
// マイリストタイトル | |
var title = $("channel > title").text() | |
.match(/^.+?\s(.+)\u2010[^\u2010]+?$/); | |
if (!title || title.length-1 > 1) { | |
ret.title = "No title"; | |
} else { | |
ret.title = title[1]; | |
} | |
// マイリスト説明 | |
ret.description = $("channel > description").text(); | |
// マイリスト所有者 | |
ret.creator = $("channel > dc\\:creator").text(); | |
// 非公開ならここで返す | |
if (!ret.creator) { | |
ret.title = "このマイリストは非公開です"; | |
return ret; | |
} | |
// マイリストID | |
var id = $("channel > link").text().split("/"); | |
if (!id) return ret; | |
ret.id = id.slice(-1)[0]; | |
// マイリストアイテム | |
$("channel > item").each(function (i, elem) { | |
var item_data = { | |
title: "", | |
video_id: "", | |
thumbnail_url: "", | |
length_seconds: 0 | |
}; | |
var description = $(this).children("description").text(); | |
// タイトル | |
item_data.title = $(this).children("title").text(); | |
// ID | |
item_data.video_id = | |
$(this).children("link").text().split("/")[4]; | |
// サムネイルURL | |
item_data.thumbnail_url = | |
description.match(/http:\/\/.+\.smilevideo\.jp\/smile\?i=[0-9]+/)[0]; | |
// 再生時間(秒) | |
item_data.length_seconds = 0; | |
var length_second = | |
description.match(/<strong class="nico-info-length">([0-9|:]+?)<\/strong>/); | |
if (length_second && length_second[1]) { | |
length_second = length_second[1].split(":"); | |
length_second = (length_second[0]-0)*60+(length_second[1]-0); | |
item_data.length_seconds = length_second; | |
} | |
// 配列に追加 | |
ret.item.push(item_data); | |
}); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment