MATLAB Answers での回答者週間ランキング（日本向け）

# やったこと

:::note warn
2023/08/15 追記
ThingSpeak からの Tweet が現在機能していないので今は GitHub Actions と Twitter API v2 を使うよう調整予定です。そのうち詳細記載します。
:::

MATLAB Answers[^1] での貢献度ランキング[^2] から、日本語の質問にも回答しているユーザーを吸い出して**勝手に**発表することにしました。

[^1]: MATLAB Answers？: MathWorks が運営する MATLAB/Simulink に関する Q&A サイトです。スタッフ（社員）も回答していますがユーザー同士のやりとりも多数。

[^2]: https://jp.mathworks.com/matlabcentral/answers/contributors （自分も「全期間」で 70位前後にいます :) ）

↓ こんな感じ。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">日本語でも回答する活躍中のユーザー（週間ランキング）<br>10位: Kenta Itakuraさん<br>19位: Akira Agataさん<br>26位: madhan raviさん<br>32位: Kazuyaさん<br>47位: Kojiro Saitoさん<br>一覧 -&gt; <a href="https://t.co/1sF7UYthew">https://t.co/1sF7UYthew</a></p>&mdash; MATLAB Answers JP bot (@JPMATLABAnswers) <a href="https://twitter.com/JPMATLABAnswers/status/1179984222003634176?ref_src=twsrc%5Etfw">October 4, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


今の状態だと、3つくらいの質問に回答すると[^3]週間ランク入りできそうですので、うずうずした方は是非。

[^3]: 評価 8 ポイントあたりが足切りのようです。回答が質問者によって'採用'されると 4 点、回答に'投票' (いいねみたいなもの）が付くと2点。

Bot ベース機能は [Qiita: ThingSpeak x MATLAB で Twitter bot 実装](https://qiita.com/eigs/items/4342676a1d453733d514)で紹介しましたので、この記事では HTML ソースから MATLAB Answers の週間ランキング情報の抽出方法を解説します。



# 環境

- MATLAB R2019b
- Text Analytics Toolbox 
    - [htmlTree関数](https://jp.mathworks.com/help/textanalytics/ref/htmltree.html?s_eid=PSM_29435)
    - [findElement 関数](https://jp.mathworks.com/help/textanalytics/ref/htmltree.findelement.html?s_eid=PSM_29435)
    - [extractHTMLText 関数](https://jp.mathworks.com/help/textanalytics/ref/htmltree.extracthtmltext.html?s_eid=PSM_29435)


# ランキング情報の抽出

ランキングページ（https://jp.mathworks.com/matlabcentral/answers/contributors） はこんな構成になっています。トップの Walter さんは一週間に97個も回答してるんですが・・。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149511/1a5c9cc8-9aaa-a037-6332-0687333e3d1d.png)


さて、このページのソースから順位、アカウント名を取ります。

１ページあたり50人だけの表示なので、以下コードで 2 ページ分のランキング情報取ってきます。

```matlab:tweetWeeklyRanking_JP.m
perpage = 50;
pages = 2;
ranks = zeros(perpage*pages,1); % 配列事前確保
names = strings(perpage*pages,1); % 配列事前確保

for ii=1:pages
    url = "https://jp.mathworks.com/matlabcentral/answers/contributors/" ...
        + "?filter=week&page=" + ii;
    
    htmlSource = webread(url); % webread でソースを取得
    htmlTree = htmlTree(htmlSource); % htmlTree でパース
    elementTree = findElement(htmlTree,"td:first-child");
    
    for jj=1:perpage
        index = (ii-1)*perpage+jj;
        tmp = findElement(elementTree(jj),"div:first-child");
        ranks(index) = extractHTMLText(tmp);
        tmp = findElement(elementTree(jj),"H4 > A > SPAN");
        names(index) = extractHTMLText(tmp);
    end
    
end
```

**CSS Selectors** (`div:first-child`/`H4 > A > SPAN`)とやらを使って、順位とアカウント名に該当する箇所を吸い出しました。うまくいきましたが正直なところソースと睨めっこしながら、半分当てずっぽうでいろいろ試した結果です。。


# Twitter 投稿

ここでは、過去日本語の質問に答えてくれた人のリスト `nicknames_JP` (String型配列) を使います。（すいません、これだけは公開できない方法で取っています。）上で100位までのアカウント名が取れましたので、`ismember` 関数を使って日本語の質問にも答えてくれているユーザーを抽出します。

```matlab:tweetWeeklyRanking_JP.m(cont.1)
%
% (nicknames_JP 作成): 省略
%
idx = ismember(names,nicknames_JP); 
dataset = table(ranks(idx),names(idx),'VariableNames',{'rank','nickname'});
```

Twitter 投稿部分の `api_key` は伏せています。改行部分に多少手間取りましたが、`newline` で解決。

```matlab:tweetWeeklyRanking_JP.m(cont.2)

api_key = 'XXXXXXXXXXXXXXX';

% 新しい投稿を Tweet
% ThingTweet 設定
tturl='https://api.thingspeak.com/apps/thingtweet/1/statuses/update';
api_key = 'XXXXXXXXXXXXXXX';
options = weboptions('MediaType','application/x-www-form-urlencoded');
options.Timeout = 10;

% 投稿文作成
thisURL = "https://jp.mathworks.com/matlabcentral/answers/contributors?filter=week";

status = "日本語でも回答する活躍中のユーザー（週間ランキング）" + newline;

for ii=1:min(height(dataset),5)
    status = status + dataset.rank(ii) + "位: " ...
           + dataset.nickname(ii) + "さん" + newline;
end
status = status + "ありがとうございます！";
status = status + "一覧 -> "  + thisURL;
disp(status);
try
    webwrite(tturl, 'api_key', api_key, 'status', status, options);
catch ME
    disp(ME)
end
```

# まとめ

欲しい情報をHTMLからとってきて、Tweet する作業を紹介しました。
恥ずかしながら、当初 String型の `newline` の存在を知らず、投稿文を改行するにはどうしたら・・と困りました。何らかの参考になりましたら。