LoginSignup
36
16

More than 5 years have passed since last update.

2年目プログラマがQiitaに週一投稿して1年が過ぎ更に1年が過ぎ更に1年が過ぎました

Last updated at Posted at 2018-05-30

底辺プログラマの赤裸々なQiita活動を統括するポエム記事第3弾です。
タイトルが荒ぶってきました。

去年と一昨年はこちら

まとめ

ネタ切れを危惧し投稿ハードルをさらに下げた結果、投稿数が倍増しました。1

いいね獲得は体感、難しくなってきています。
外的要因とするならば日本のエンジニアのレベルが向上しているのか、Qiitaの新レイアウトのせいなのか。
Qiitaでいいね獲得を目指すならば、技術的な一芸に秀でたプログラマになるか、一芸に秀でたポエマー表現者になる道がある気がします!

今年を振り返ってQiitaへの投稿をオススメするなら

新人プログラマ応援タグをつけているので曲りなりにも先に有益そうな個人の意見を。

ストイックに、自分が学んだこと・詰まったことの技術的解決メモを残したい人なら

いいね数には覚悟が必要かもしれません。
私も0いいねでも個人的に満足している記事はありますので、
いいねがつかない記事≠悪い記事
だと思います。
いいねがつかないと段々気持ちが沈んでいくというのは実感としてはあります。
でもだからと言って投稿をやめる理由、ローカルのメモ帳に戻る理由にはならないんじゃないかな。
やっぱりQiitaでなくても良いんですが、オンラインに書くことはそれ自体が刺激的で良いことだと思います。

(ほんとうに困っているときに助かる記事って0から十数いいねぐらいまでのものが多かったりするんですよね)

やったことの記録を取りたい人なら

ストーリーが大事だと思います。
自分の困ったこと、思ったこと、やりたかったことを読みやすく書いて、できれば画像なども矢印・テキストで加工しながら貼り付けましょう。
途中経過も大事。
あなたが感じた大切なことを書ききれれば、共感を与えられる可能性はあります。
なんだかんだで背景や物語、流れといったものがある方が記事は読みやすかったり記憶に残りやすかったりしますしね。
ITエンジニアに関するという前提は外れませんが、なぜそうしたか・そう感じたかという記録は、読み手にも振り返る未来の自分にも大事になるかもしれません。

どちらもタイトルを大事に

トレンドとタイムラインを除いて記事が最初に表示されるのは「タグフィード」と「すべての投稿」です。
主に見られるタグフィードにはいいね数などが出ないので、既に100いいねついた投稿も0いいねの投稿もタグフィード上ではタイトルに惹かれるかどうかが見てもらえる基準じゃないかなと思います。
一年目と同じことになりますが、やっぱりメモと書くのはもったいないな、と。

タグも大事に

タグフィードに乗るためにはフォローされているタグを記事につける必要があります。
補完機能を使って、できるだけ投稿数が多いタグをつけましょう。
言語やOSのバージョンなどはタグにつけると極端に減ることがあるので、その場合は本文に乗せて、タグはできるだけメジャーにしましょう。

投稿アクティビティ

毎年お世話になります。
Qiitaの投稿アクティビティをGitHubのように表示するヤツ - Qiita

image.png

下書きに溜まっているのでほぼ月曜日の朝に即投稿していました。

戦闘力

Qiitaの統計はちょくちょく出ますが、今年は統計に加え戦闘力が測れます。

image.png

リアルタイムではないですが、4月ごろのデータでナッパだそうです。ナッパは喜ばしいのか?
平均Contribution数はやっぱり寂しいですね…打率の低さが伺えます。

現在は、一記事あたり平均6Contributionなのに対し、2014年4月は34Contributionであり、実にピーク時の5.5倍も差が開いている。Contribution数の総和が下落傾向なのに、投稿記事数は右肩上がりなので、Contributionの獲得難易度が大きく上がっているようだ。
第一回 チキチキQiita戦闘力ランキング選手権 - Qiita

平均値と言えなくもないですが、今年の投稿に目を向けると…

一年間の投稿記事

このままでは技術的記事だという言い訳ができないので、去年作った記事一覧を出力するコードに、いいね数を追加しようと思います。

去年は想定していなかった機能なので、かなり無理やり追加しました。

いいね数を表示するようにしたテーブル出力.js
var request = require('request');

// 方針
// テーブル記法の見栄え優先で、リンクは分離式でいく
// タイトルの最大文字数によってヘッダーのセパレーターや各行の余白が異なるので、最後に出力する。
// タイトルの最大長は[]を含めたものとするが、左右の見栄えのための空白は含めないものとする
// 表示は等幅フォントを想定し、長さをカウントするときは、全角文字を2とカウントする

// 全角を2とカウントする http://blog.tofu-kun.org/070627210315.php
const strLength = (strSrc) => {
    var len = 0;
    strSrc = escape(strSrc);
    for(var i = 0; i < strSrc.length; i++, len++){
        if(strSrc.charAt(i) == '%'){
            if(strSrc.charAt(++i) == 'u'){
                i += 3;
                len++;
            }
            i++;
        }
    }
    return len;
};

const createHeader = (maxTitleLength) => {

    const marginLength = 2;
    const dateLength = 14; // XXXX年XX月XX日(全角は2)
    const likeLength = 3; // 1000いいねはありえないので(100も…まあ…)
    const titleLabel = 'タイトル';
    const dateLabel  = '投稿日時';
    const likeLabel = 'いいね';

    var header =
    '| '  + titleLabel + ' '.repeat(maxTitleLength - strLength(titleLabel)) +
    ' | ' + dateLabel  + ' '.repeat(dateLength     - strLength(dateLabel)) +
    ' | ' + likeLabel  + ' |'; // ラベルのほうが長いので

    var separator =
    '|' + '-'.repeat(marginLength + maxTitleLength) +
    '|' + '-'.repeat(marginLength + dateLength) +
    '|' + '-'.repeat(marginLength + strLength(likeLabel)) + '|';

    return header + '\n' + separator;
};

const createRow = (maxTitleLength, item) => {
    var date = new Date(item.created_at);
    date = date.getFullYear() + '' + ('0' + (date.getMonth() + 1)).slice(-2) + '' + ('0' + date.getDate()).slice(-2) + '';
    var padding = maxTitleLength - strLength(item.title) -2; // maxに[]は含まれているので、ここで差っ引く
    return '| [' + item.title + ']' + ' '.repeat(padding) + ' | ' + date + ' | ' + item.likes_count.toString().padStart(3 + 3/* いいねが6でヘッダーのほうが長いため場当たり */) + ' |';
};


// maxTitleLengthは4以上を想定している
const createTable = (maxTitleLength, items) => {
    var table = '';
    table = createHeader(maxTitleLength, items);
    for (var i in items) {
        table = table + '\n' + createRow(maxTitleLength, items[i]);
    }
    return table;
};



const userId   = 'khsk';
const dateFrom = '2017-05-30'; // fromは予約語かな
const dateTo   = '2018-05-30';
// 48投稿前後なのでページ処理はしない
const url = 'https://qiita.com/api/v2/items?per_page=100&query=user:' + userId + '+created:>' + dateFrom + '+created:<' + dateTo;

request.get(url ,(error, response, body) => {
    var obj = JSON.parse(body);
    console.log(obj.length + '投稿\n');

    // タイトルの最大長と分離リンクを作成するループ
    var linkList = []; // リンク先のURL参照を持つ配列
    var max = 0; // タイトル最大長
    for (var i in obj) {
        var item = obj[i];
        var date = new Date(item.created_at);
        max = Math.max(max, strLength(item.title));
        linkList.push('[' + item.title + ']: ' + item.url);
    }
    max = max + 2; // タイトルを囲む[]分を加算

    // 2回ループ回すの気持ち悪いなあ
    var table = createTable(max, obj);

    // リンク出力
    linkList.forEach((e) => {
        console.log(e);
    });
    console.log('\n');

    console.log(table);
});

手動で作らずライブラリを駆使するなら
wooorm/markdown-table: Markdown tables, with alignment
などが手軽そうでいいですね。

結果

94投稿


今年の投稿記事
タイトル 投稿日時 いいね
brew (un)?instal にはaliasが張られている ~ パッケージマネージャーには意外とある 2018年05月21日 2
textlint-filter-rule-whitelistとルール独自のallowオプションによる正規表現の違いに注意する 2018年05月21日 2
GASでセブンイレブンの今週の新商品をスクレイピングして通知する 2018年05月14日 131
Nimで言語処理100本ノック 02. 「パトカー」+「タクシー」=「パタトクカシーー」 2018年05月09日 1
Node.jsでSVNからcheckoutするためにsvn-spawnを使う 2018年05月07日 1
Nimで言語処理100本ノック 01. 「パタトクカシーー」 2018年05月02日 1
Nimで言語処理100本ノック 00. 文字列の逆順 2018年05月01日 2
新しい言語/ライブラリにふれるときに知っていると得するかもしれない検索キーワード 2018年04月24日 6
プロンプトに活動限界時間を表示する 2018年04月23日 2
remiを入れているのに No package php72 available. など出たらexclude=php*を疑う 2018年04月19日 1
JavaScriptで'key=value&key2=value2…'StringをObejctに変換するには 2018年04月18日 1
ESLintのルールを全部手動で設定するのは大変だからやめておけ 2018年04月13日 145
人間性をさがせよ QiitaのTypo検出 【緩募】 2018年04月10日 54
Puppeteerでlibnss3.so: version `NSS_3.22' not foundと出たら 2018年04月02日 0
sudoで実行するスクリプトに環境変数を渡すには-Eオプション 2018年04月02日 0
vscode-backgroundのRandom buckground imageの展望 2018年03月29日 0
Officeファイルを狙ったサイズにするために再圧縮する 2018年03月26日 0
Qiitaの狭幅レイアウト時のモーダル検索バーにフォーカスするユーザースクリプト 2018年03月26日 1
Qiitaの左側メニューにリンクを追加するユーザースクリプト 2018年03月22日 0
お尻(単語末尾)が欠けている正規表現は否定的先読み 2018年03月16日 1
@slack/client 4.0.0 の IncomingWebhook sendとレスポンスエラー(ParseError: Unexpected token o in JSON at position 0) 2018年03月13日 2
SublimeText3 で WARNING: eslint cannot locate 'eslint' 2018年03月09日 2
jQuery UI ダイアログのリサイズ時にselectリストのsizeを連動させる 2018年03月09日 1
Puppeteerでdialog OK後のdialogを捕捉 2018年03月06日 1
アドオンが動作しない潔癖症ユーザーが確認すべき場所の一つはCookie 2018年03月05日 0
QiitaでCodePenの埋め込みコードが見れない 2018年03月01日 1
Unix タイムスタンプを渡しDateTimeは作れる。が比較はUnix タイムスタンプ同士がよくないか 2018年03月01日 2
error_log風味のファイル書き込み 2018年02月27日 1
ElectronのWebviewで履歴の戻る/進む ~手巻き寿司を添えて~ 2018年02月26日 2
at.jsはinputにも使える(不正動作あり) 2018年02月22日 1
新 Qiitaのフィードから特定ユーザーの投稿を非表示にするユーザースクリプト 2018年02月21日 2
lolcatやNeo Cowsayみたいに文字を色付けするgolorコマンドをはじめてGo言語を触りながら作った 2018年02月19日 2
ストックしたQiita記事をSlackへランダムに通知するHubotスクリプト 2018年02月14日 1
過剰なリファクタリングライン コピペ(共通化・抽象化)編 2018年02月07日 9
複数のデリミタによるexplodeは何が速いか 2018年02月05日 4
urfave/cliのグローバルオプションへのアクセス方法 2018年02月02日 0
昔の人はどんなダジャレを本のタイトルに仕込んだのか 2018年01月29日 4
Slackの推奨環境ヘルプを見て目からうろこが落ちた 2018年01月22日 63
新レイアウトになってQiitaに投稿するときに気をつけること あるいは過去記事の修正 2018年01月18日 2
stack install package しても stack buildでCould not find moduleが出る 2018年01月18日 5
んで、結局Contributionのうち、投稿で勝ち得たいいねはどれぐらいなのさ 2018年01月16日 2
配列群の最大・最小長を取得するには 2018年01月12日 1
runnable.comに接続するとhttps://www.wowrack.com/1GB.fileに飛ばされる 2018年01月10日 1
Firefoxでタブを分離したときに最大化するアドオン 2018年01月09日 5
parcelでconsoleを残しつつビルドする 2018年01月05日 3
parcel installしようとしてNo matching version foundエラー 2017年12月26日 2
PHP5.4に対応するXdebugは2.4.1 2017年12月25日 2
素因数分解を使ったテクくもない遠回りFizzBuzz with Ruby 2017年12月18日 0
sudo (grep or pgrep -f) はプロセス数がsudo分増えるよ 2017年12月12日 1
Qiitaの通知画面のリンクをすべて開くブックマークレット 2017年12月11日 1
MySQLからSELECTした値をINSERTするときにエスケープは必要か? 2017年12月07日 0
Kotohaを使って実行前のコマンドラインにアニメの名言を入れるzshスクリプト 2017年12月04日 2
U+001DなどUnicode(ASCII,C0)制御文字がHeaderに含まれるとaborting requestするので除去する 2017年11月29日 0
Laravel4までのBladeでエスケープしつつデータ表示は波括弧三重{{{}}}。PhpStormには設定書き換えが必要 2017年11月21日 0
抽象クラスを継承した抽象クラス(abstract class Sub extend Super)は抽象メソッドを実装しなくてよい 2017年11月20日 1
await hoge() SyntaxError: Unexpected identifier 2017年11月13日 1
Staticなクラスの__destructを擬似的に呼び出すのに他のクラスは必要か 2017年11月13日 0
sed -ie "s/ho/ge/" filename は意図通りではないかもしれない 2017年11月10日 4
Qiitaの通知の分類をした…かったユーザースクリプト 2017年11月06日 5
button要素にはhref属性を持つa要素を(本来は)含めてはいけない。 2017年11月01日 3
Content-Disposition: attachment; filenameのrfc 6266形式 2017年10月30日 3
Firefoxのコンソール出力画面でString.fromCharCode(160)【 】が半角スペースになる 2017年10月24日 1
ウィンドウタイトルを指定してその領域だけを定期的に保存する 2017年10月16日 0
開発環境では動くけれどビルドするとエラーを吐くPyQtコード:ボタン(Qt)による終了 2017年10月12日 0
開発環境では動くけれどビルドするとエラーを吐くPyQtコード:QString 2017年10月10日 0
Spyderで2度めのPyQtが実行出来ない 2017年10月04日 0
pythonからtesseractを使った場合のUnicodeDecodeError: '文字コード' codec can't decode byte 0x81 回避 2017年10月02日 0
Qiitaの記事でフォロイーのいいねを表示するユーザースクリプト 2017年09月26日 2
引数の数をcountでチェックするなら一度変数に入れる 2017年09月20日 1
phina.jsでグリッド内を一歩一歩八方に移動する 2017年09月15日 4
phina.jsで改善されたグリッド内に画像を表示する 2017年09月05日 1
phina.jsでbase64形式で画像を使う 2017年09月04日 0
phina.jsでグリッドに四角形を敷き詰める 2017年09月04日 2
phina.jsで内部が透明な図形を作るには shape.fill = 'transparent' 2017年09月04日 0
たとえば5分ごとにcronを実行しない 2017年08月30日 9
新はてなブックマークで本文をトップに表示する&お気に入りユーザーのコメントをポップアップさせるユーザースクリプト 2017年08月22日 3
はてブではてなお気に入りユーザーのスターを強調するユーザースクリプト 2017年08月17日 1
【未解決】特定条件行の特定文字をすべて置換する正規表現 2017年08月09日 0
ミスって0秒で即fuck ~ 自動fuckしたいだけの人生だった 2017年08月07日 1
ログイン毎に異名をつけるプロンプト 2017年07月31日 7
Phina.jsの最新版はパッケージマネージャーからインストールできないかもしれない 2017年07月27日 0
fishのfunctionをpecoで選択 2017年07月24日 1
PHPカンファレンス関西2017行ってきたよ 2017年07月18日 9
~dots.~TECH PLAYの大阪新着RSS by Feed43 2017年07月11日 0
PHPでも過激な短絡評価がしたい! 2017年07月10日 2
PaintsChainerをSeleniumで操作しディレクトリ内画像を自動着色 2017年07月03日 0
Selenium WebDriverをPythonで動かしているときにファイルの選択のsend_keysでフリーズする【PhantomJS】 2017年06月27日 0
GreasemonkeyのunsafeWindowの移行タイミングのひとつはgrant 2017年06月27日 0
任意の文字列をコピーするテクニック 2017年06月26日 3
QiitaでFont Awesome諸々が死んだ ユーザーインプットフィルターの導入 2017年06月19日 22
それでいいのかインサート 2017年06月19日 1
Vuexのstoreの、load・unload時の復元・保存 2017年06月12日 5
Vuexが使えない場合に 確認すべき初歩的な箇所 2017年06月05日 1
2年目プログラマがQiitaに週一投稿して1年が過ぎ更に1年が過ぎました 2017年05月30日 17

毎年ですが難しいことを全然していませんね。
逆に言えば、簡単なことだけでも、いち記事最高150いいね未満でも3年続ければ合計で4桁いいねまでいけるということがわかりました。

4月からの3記事でかなり平均値を助けてくれています。
普通に書くと2桁いかず、たまに伸びると50超え。とかなり振れ幅が大きいです。
それもこれもトレンドに載った影響なので、トレンドに乗らずば記事にあらず…といった気持ちもなくはないです。


うっかり100記事以上投稿するとShiiba含めページングしていないこのスクリプトも漏れがでるので、5末は逆に投稿しすぎてないか不安になりました。まさかこんな日が来るとは週一に四苦八苦していたときには露程も思わず…。

いくつか記事の振り返り

ミスって0秒で即fuck ~ 自動fuckしたいだけの人生だった

記事を書ききったときは「このタイトルしかない!」と思いましたが、冷静になると人を寄せ付けないタイトルだと気づきます。

今は美少女に罵られながらfuckしてもらっています。(反省していない。


んで、結局Contributionのうち、投稿で勝ち得たいいねはどれぐらいなのさ
は単純になにも考えずつけた悪い例です。

phina.jsで~シリーズ

もう一本、部屋と道を作成して移動不可のタイル(壁)を設定して徘徊できるところまで作って一応の終わりとしたんですが、タイミングを逃してその部分を投稿できてないです。
ローカルで作るとファイルを分割してrequireできるのですが、runstantに貼るときに手動で一つのファイルにするのが面倒で遠のきました。

今ゲーム系を触るならメロンも良さそうです。

ESLintのルールを全部手動で設定するのは大変だからやめておけ

image.png

最いいね数とっちゃった問題児。タグに入れてませんがやはりポエム枠ですね。

普段通り「苦労したこと(結論)→動機(目的)→経緯→参考」と書いていたら、経験上1いいねの内容だろうと思っていた内容を、直前の記事のいいね数がよかったので開き直って「逆噴射文体」で書きました。

伸びていくいいね数を眺めながら、今後全記事を(Qiitaでは)邪道と感じる「逆噴射文体」で書くか真剣に悩みました。
戸田奈津子 vs 逆噴射聡一郎
なんてワードも浮かびました。

しかし、いいねが増えて嬉しい一方、こんな記事がのびすぎるのはQiitaとして良くはないよなあと。2

ただし、普段よくないとわかりつつもどうしても使ってしまう弱い表現を廃して、断言・命令口調で書けるのは気持ちがいいので、ひっそりとまた書くかもしれません。

Contribution

今年
image.png

去年

フォロワーが増えましたが、ほとんどがESLintポエムと編集リクエスト活動の賜物なので、にゃんとも。
Contributionも記事のいいねが貰えないため、編集リクエスト活動で無理やり稼いでいます。

グラフは累計の推移ではなく増分になりましたね。

今年の裏テーマが1000Contribution達成だったので良かったです。

純いいね数

んで、結局Contributionのうち、投稿で勝ち得たいいねはどれぐらいなのさ
で再度見ます。
この投稿以降に編集リクエスト活動を増やしたので増分が気になります。

当時の純いいねが1月で926。当時で約50の差分と書いてます。
編集リクエスト候補の自動リストアップを3月後半からはじめて…
4ヶ月後の現在のContributionが1720。
純いいねが1465。
あっというまに200Contributionほどのいいね外のContributionが得られました。
3年で50が2ヶ月ほどで200なので、かなりの上昇率です。
1いいねの記事を書くよりは編集リクエスト書いている方が儲かるくらい。…儲かる?

印象に残っている投稿

記憶だよりなのでどうしても最近の記事になるのですが





  • よく使う正規表現はもうググりたくない! - Qiita
    記事の出発が正しくなくても?第三者の良いコメントが寄ってきて知見が集まり投稿者が評価されるなら、間違っているかもしれなくても投稿できるようにハードルが下がる流れがくるのかな?
    などと考えていた気がします。




  • npxが結構良さそうな件について - Qiita
    代わり映えしない開発環境生活ですが、npxは明確によく使うようになったと思います。
    とくにローカルにインストールしたときにパスを通さなくてもnpx パッケージ名で実行できるので、パスを記述する手間が減りました。

来年への準備

最近、GASを学んだので、1年ごとのContributionの記録ではなく、日々の記録をスプレッドシートに取ろうかと考えています。
あいにく着手が最近で今年は間に合いませんが、1年間ブラッシュアップして、Contributionの1年間の増加を見れればと思います。

スクリーンショット

作りかけの現状です。

image.png

image.png

コード

現在作成中のコードです。
ライブラリはParser。
Easy data scraping with Google Apps Script in 5 minutes ~ kutil.org

function main() {
  var spreadsheet = SpreadsheetApp.openById('~')
  var userData = updateUserData()

  Logger.log(spreadsheet)
  Logger.log(spreadsheet.getLastRow())
  var logSheet = spreadsheet.getSheetByName('ログ')
  if (logSheet.getLastRow() == 0) {
    initSheet(logSheet)
  }
  var today = Utilities.formatDate(new Date(), 'asia/tokyo', 'yyyy/MM/dd')
  logSheet.appendRow([
    today,
    userData.items,
    userData.contributions,
    userData.followers,
    userData.diffItems,
    userData.diffContributions,
    userData.diffFollowers,
    userData.titles
  ])

  // グラフ作成 todo 関数化

  var graphSheet = spreadsheet.getSheetByName('グラフ')
  // 毎回新規に作るので、既存のグラフは削除する(addRowで追記式のほうがスマートだろうけど)
  rmAllCharts(graphSheet)

  // グラフのサイズ関連がまだわかってないので今後重なったりするかも。1シート1グラフのほうがいいかなあ
  // シートから作る embeddedchartbuilder では .setDataViewDefinition(viewSpec) がなく、setOptionで annotations.styleも効かせられないので、ラベルの縦書きが実現できていない。
  // 今からChatr.newChartで作り直すのも面倒なので、機能拡張待ちとしたい。

  var range = logSheet.getRange('A1:D' + logSheet.getLastRow())
  var postTitle = logSheet.getRange('H1:H' + logSheet.getLastRow())
  var chart = logSheet.newChart().addRange(range).addRange(postTitle)
  .setChartType(Charts.ChartType.LINE)
  .setOption('title', '累計グラフ')
  .setNumHeaders(1)
  .setPosition(1, 1, 0, 0)
  .setOption('pointSize', 5)
  .setOption('series', {
    0: {
      targetAxisIndex:1,
      pointShape: 'circle'
    },
    1: {pointShape: 'circle'},
    2: {
      targetAxisIndex:1,
      pointShape: 'circle'
    }
  })
  .setOption('roles', {
    3: {type:'annotation'}, // 記事名を注釈・特異点?化
  })
  .setOption('focusTarget', 'category') // 比較モード。同日の全てのツールチップ表示
  .setOption('theme', 'maximized') // グラフ最大化
  .build()  
  graphSheet.insertChart(chart)

  var dateRange = logSheet.getRange('A1:A' + logSheet.getLastRow())
  range = logSheet.getRange('E1:G' + logSheet.getLastRow())
  chart = logSheet.newChart().addRange(dateRange).addRange(range).addRange(postTitle)
  .setChartType(Charts.ChartType.LINE)
  .setOption('title', '差分グラフ')
  .setNumHeaders(1)
  .setPosition(25, 1, 0, 0)
  .setOption('pointSize', 5)
  .setOption('series', {
    0: {pointShape: 'circle'},
    1: {pointShape: 'circle'},
    2: {pointShape: 'circle'}
  })
  .setOption('roles', {
    3: {type:'annotation'}, // 記事名を注釈・特異点?化
  })
  .setOption('focusTarget', 'category') // 比較モード。同日の全てのツールチップ表示
  .setOption('theme', 'maximized') // グラフ最大化
  .build()
  graphSheet.insertChart(chart)
}

function updateUserData() {
  var userId = 'khsk'
  var URL  = 'https://qiita.com/' + userId
  var html = UrlFetchApp.fetch(URL).getContentText()

  var getUserStateCount = (function(html){
    return function(key) {
      return Parser.data(html)
      .from('/' + key + '"><span class="userActivityChart_statCount">')
      .to('</span>').build()
  }})(html)

  var items         = getUserStateCount(userId)
  var contributions = getUserStateCount('contributions')
  var followers     = getUserStateCount('followers')

  // ScriptPropertiesからとっているのは最初GAS完結していた通知スクリプトをグラフに使おうとしたので、シートからの計算をサボっている。

  var ScriptProperties = PropertiesService.getScriptProperties()
  var oldItems         = ScriptProperties.getProperty('items')         || items
  var oldContributions = ScriptProperties.getProperty('contributions') || contributions
  var oldFollowers     = ScriptProperties.getProperty('followers')     || followers

  var diffItems         = parseInt(items         - oldItems)
  var diffContributions = parseInt(contributions - oldContributions)
  var diffFollowers     = parseInt(followers     - oldFollowers)

  ScriptProperties.setProperty('items',         items)
  ScriptProperties.setProperty('contributions', contributions)
  ScriptProperties.setProperty('followers',     followers)

  // key名省略はes2015だからむりー
  return {
    'items'             : items,
    'contributions'     : contributions,
    'followers'         : followers,
    'diffItems'         : diffItems,
    'diffContributions' : diffContributions,
    'diffFollowers'     : diffFollowers,
    'titles'            : getNewPostTitles(html, diffItems)
  }
}

function initSheet(spredsheet) {
  spredsheet.appendRow(['日付', '投稿数', 'Contiributions', 'フォロワー', '投稿数増分', 'Contiributions増分', 'フォロワー増分', '投稿記事'])
}

function rmAllCharts(spredsheet) {
  var charts = spredsheet.getCharts()
  charts.forEach(function(chart) {
    spredsheet.removeChart(chart)
  })
}

function getNewPostTitles(html, newCount) {
  var titles = ''
  var separator = '\n'

  var posts = Parser.data(html)
  .from('<div class="ItemLink__title">')
  .to('</div>').iterate()

  for(i = 0; i < newCount; ++i) {
    Logger.log(posts[i])
    Logger.log(posts[i].match(/">(.+)<\/a/)[1])
    titles = titles + posts[i].match(/">(.+)<\/a/)[1] + separator
  }
  return titles.trim(separator)
}

ユーザーページのスクレイピングは以下も参考に


今年は以上です。
お仕事がらから新しいことはあまりなく、Qiitaを書く習慣もついたのでもう最低週一投稿にあまり強くこだわってませんが、記録としては面白いのかもとも思うので、うまく行けばまた来年があるかもしれません。


  1. 投稿しない下書きが溜まっていることも原因です。Qiitaの方針で下書き数は増えないみたい。
    https://twitter.com/htomine/status/984355071491100678 

  2. 150いいねいかない程度、バズの範疇にも入りませんが。 

36
16
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
36
16