承認これくしょん

my black histories

WSHで指定したTwitterアカウントが投稿した画像をだいたい全部ダウンロードする

公式Webクライアントの「画像/動画」タブに出てくるpic.twitter.comにアップロードされた画像をダウンロードする。
外部サービスは対象外、またRTしたツイートが含まれることがあるので「だいたい」。
bignumber.jsを使ってるので一緒にディレクトリに入れてください。
あと今回はCS/CKは不要です。理由はコード見ればわかると思う。

使い方

cscript download.wsf (アカウント名)

画像はアカウント名のサブディレクトリに保存される。

コード

download.wsf
<job>
<script language="JScript" src="bignumber.js" />
<script language="JScript">

var fso = new ActiveXObject('Scripting.FileSystemObject');
var xhr = new ActiveXObject('Msxml2.XMLHTTP');
var sw = new ActiveXObject('ADODB.Stream');

var screenName = WScript.Arguments(0);
var currentPath = String(WScript.ScriptFullName).replace(WScript.ScriptName,'');
var outPath = currentPath + screenName + '/';
if (!fso.FolderExists(outPath)) fso.CreateFolder(outPath);

var baseURL = 'https://twitter.com/i/profiles/show/' + screenName + '/media_timeline';
var imageCount = 0;

do {
    var json = getJSON(lastId);
    var document = new ActiveXObject('htmlfile');
    document.write(json.items_html);
    getImages(document);
    var lastId = getOldestTweet(document);
    document = null;
} while (json.has_more_items == true);

WScript.echo(imageCount + '個のファイルをダウンロードしました。');

fso = null;
xhr = null;
sw = null;

function getJSON(lastId) {
    var params;
    if (!lastId) {
        params = '';
    } else {
        var nextId = new BigNumber(lastId);
        nextId = nextId.subtract(1);
        params = '?contextual_tweet_id=' + lastId + '&include_available_features=1&include_entities=1&max_id=' + nextId;
    };
    xhr.Open('GET', baseURL + params, false);
    xhr.send();
    return eval('(' + xhr.responseText + ')');
}

function getImages(document) {
    var elements = document.getElementsByTagName('img');
    for (var i = 0; i < elements.length; i++) {
        if (elements[i].src.search(/https:\/\/pbs.twimg.com\/media\/\S+:large/) != -1) {
            var url = elements[i].src.replace(':large', ':orig');
            xhr.Open('GET', url, false);
            xhr.send();
            sw.Open();
            sw.Type = 1; //adTypeBinary
            sw.Write(xhr.responseBody);
            sw.Savetofile(outPath + url.replace(/https:\/\/pbs.twimg.com\/media\/|:orig/g, ''), 2);
            sw.Close();
            WScript.echo(url);
            imageCount++;
        };
    };
};

function getOldestTweet(document) {
    var tweetId;
    var elements = document.getElementsByTagName('div');
    for (var i = 0; i < elements.length; i++) {
        if (elements[i].getAttribute('data-tweet-id')) {
            tweetId = elements[i].getAttribute('data-tweet-id');
        };
    };
    return tweetId;
};

</script>
</job>

所感

  • JSONをevalするのは良くない、WSHでjson2.js使えるのかな?
  • ECMAScriptの数値はdoubleなのでツイートIDを扱うには精度が足りない