Qiitaの「いいね」がダメならば


2020/03/29 追記：本記事で作成されているbotは稼働停止しました。ご利用いただいた方々、ありがとうございました。

---

最近、Qiitaの記事の品質低下に関する議論記事やネタ記事を見かけます。真面目な話をすれば、**「品質」は、顧客の評価で決まるもの**です。つまり、**人によって基準が違うもの。**例えば記事で言うと、初心者が満足する記事と、上級者が満足する記事は違います。そのため、**品質が高い／低いなどとは一概には決められません。**

でも今問題視されているのはそういうレベルの話ではなく、単純に**「記事の内容が正しくないこと」**のように見えます。「正しさ」を二の次にして、注目を浴びやすい記事を書く人が増えたのでしょう。自分が「いいね」を押しても損する人はいませんから、目を引くわかりやすいタイトルを見てなんとなく「いいね」を押す人も多いと思います。

個人的には人が増えればそうなるのも自然な話だと思いますし、それに対する[Qiitaでお金が稼げるなら質の高い記事がもっと増えるのではないかという提言](https://qiita.com/HiromuMasuda0228/items/aa3729882cb59fda9838)などの議論は面白いのですが、結果的に**議論・ネタ記事ばかりがトレンドに載り、「プログラミング」というサイトの本質からズレてしまっているのは少し違う気がします。**

# Qiitaの「いいね」がダメならば

もはやQiitaのトレンド、つまり「いいね」の数だけで記事を評価するのは難しい。それならば、**「いいね」以外の尺度を見てもいいんじゃないか？**ということで、今回は実験的に、**「Twitterのリツイート数」**に注目してみました。

リツイートするには、「いいね」よりも強い、「フォロワーに共有したい」という意志が必要です。つまり、**リツイート数が多い記事は、「みんなに見てほしいぐらい良記事」か「みんなに晒すべきほどのダメ記事」に偏るのではないか？という仮説が立てられます。**さらに問題のある記事は周りの反応を見れば初心者でもすぐわかるので、結果として良記事を拾える。かもしれない。

※ちなみに最初は、リツイート数ではなく単純に記事がツイートされた数で集計しようかと考えたのですが、単発ツイートのみで拡散される記事はそうそうないでしょうし、敢えてシンプルにリツイートに絞りました。

# 作ったもの
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/280076/8c5e37ed-ae6a-938b-d9bf-3366f4c0037e.png)](https://twitter.com/osusume446)
[Qiitaの人気ツイートをリツイートくん](https://twitter.com/osusume446)

**Qiitaの記事URLを含むツイートのうち、リツイート回数が多いツイートをリツイートします。**基準となるリツイート回数については暫定で100回として作りました。ざっくりこんな感じ。

■リツイート対象の条件
・Qiitaの記事URLを含む
・100回以上リツイートされている
・直近7日間以内に1回以上リツイートされている

※以下は対象外
・このbotが既にリツイート済み
・Qiitaの記事がサスペンドされている
・Qiita公式のツイート（トレンドに寄りそうなので）

# 作り方

シンプルにTwitter APIを利用しました。
やってることはすごく大したことないですが一応書きます。
[Standard search API](https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets)

# Search APIの呼び出し
tweepyなどのパッケージを使ってもいいのですが、大した内容でもないので地道にやってみます。基本はこのあたりにわかりやすく書かれています。
[Pythonでサクッと簡単にTwitterAPIを叩いてみる](https://qiita.com/ogrew/items/0b267f57b8aaa24f1b73)

ただし、検索対象に合わせてパラメータを指定しています。

```Python
    params = {
        'q': 'qiita.com',
        'lang': 'ja',
        'count': 100,   # 最大取得件数(max100)
        'since': 'YYYY-MM-DD（7日前）', # FROM
        'until': 'YYYY-MM-DD（当日）', # TO
        'since_id': XXXXXXXXXX, # 最小ツイートID
        'max_id': XXXXXXXXXX, # 最大ツイートID
    }
```

これで、since 〜 until の期間のツイートのうち、IDが since_id 〜 max_id の間のツイートを取得できます。引っかかりやすい（直感的ではない）と感じたポイントは2点。

**①Search API は新しいツイートから順に取得する**
直感的には古い順に取得していきそうな気もしますが、新しい順です。
また、1回の最大取得件数が100件なので何度も取得を繰り返すのですが、**「max_id」には「前回取得時の一番古いツイートのID -1」を指定してあげる必要があります。**
例えば1回目に取得したツイートIDが：999 〜 900 だった場合、2回目の取得時の「max_id」は899にします。

**②countを100にしても1件のときもある**
countは1回の最大取得件数なのですが、**100にしたからといって毎回100件取得できるわけではありません。**90件だったり80件だったり、まちまちです。最初の数回は100件取得できても、後半は1件ずつということもよくあります。件数に応じて処理を行う際は気をつける必要があります。

# リツイート情報の取得
今回は「7日間以内に**リツイート**されたツイート」を対象とします（7日間：Twitter Search APIの無料枠）。7日以上前のツイート情報であっても、7日以内にリツイートされていれば取得できます。

Twitter API で取得できるツイートオブジェクト（[Tweet objects](https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/intro-to-tweet-json)）は、**リツイート情報も入れ子の形で含むようです。**
参考：[Twitterリツイートに関するJSONについてまとめる](https://qiita.com/Suibari_cha/items/7b09eb6441acaa8fbea1)

```Python
from requests_oauthlib import OAuth1Session
import json

twitter = OAuth1Session(CK, CS, AT, AS)
SEARCH_URL = 'https://api.twitter.com/1.1/search/tweets.json'

# ツイート情報を取得
res = twitter.get(SEARCH_URL, params=params)
tweets = json.loads(res.text)

# 取得したツイート毎に処理
for tweet in tweets['statuses']:
    if 'retweeted_status' in tweet:
        retweeted = tweet['retweeted_status'] # 公式リツイート情報（引用リツイート情報は 'quoted_status'）
        id = retweeted['id'] # ツイートID
        retweet_count = retweeted['retweet_count'] # リツイート情報
        ・・・
```

# サスペンドされた記事を対象外にする
ツイートを取得してみると、サスペンドされた記事のツイートが取得されることがありました。見れない記事をリツイートしても仕方ないので、対象外にすることにします。

[Python3でURLが存在するかを確認する方法](https://qiita.com/YanaErry/items/680c61dbd1ab0e00f194)で記事が存在しない場合はリツイート対象外にします。本当はQiitaのAPIなど呼べばいいのかもですが。

# 結果
作成時のポイントはこんなところなので、最後に実際に動かしてみた結果も残しておきます。とりあえず**直近の7日間で対象となったリツイートのうち、リツイート数が上位のもの**を並べてみます。

一応、集計時点におけるQiitaの「いいね」数とTwitter上のリツイート数も合わせて書いておきます。

**1位**
Twitter：291 リツイート
Qiita：653 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">布団から腕すら出さずに会社を休む [Google Home]<a href="https://t.co/YOeaA0UQqT">https://t.co/YOeaA0UQqT</a> <a href="https://t.co/8KmSklEf5D">pic.twitter.com/8KmSklEf5D</a></p>&mdash; ポメラニウス (@pomeranian_dev) <a href="https://twitter.com/pomeranian_dev/status/924722132923252736?ref_src=twsrc%5Etfw">2017年10月29日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
「会社を休む」というおふざけとプログラミングの真面目さのギャップが良い感じの記事。みんなの休みへの欲求がリツイートさせたのかな。
<br/>
**2位**
Twitter：235 リツイート
Qiita：1273 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">これでウチなりの AtCoder に入っていくための攻略資料がひとまず完備なものになったと思うのん<br><br>入門編: <a href="https://t.co/6p5cCBIFqe">https://t.co/6p5cCBIFqe</a><br><br>初級編: <a href="https://t.co/C4DAGYBRWy">https://t.co/C4DAGYBRWy</a><br><br>中級編: <a href="https://t.co/pJzQhWEDg8">https://t.co/pJzQhWEDg8</a><br><br>上級編: <a href="https://t.co/BTUBDVjNOC">https://t.co/BTUBDVjNOC</a><br><br>あとは細々と蟻本の「発展的トピック」の類題を集めてるん。</p>&mdash; けんちょん (@drken1215) <a href="https://twitter.com/drken1215/status/973453195895742464?ref_src=twsrc%5Etfw">2018年3月13日</a></blockquote>
AtCoderというプログラミングのコンテスト？に関する記事。
<br/>
**3位**
Twitter：192 リツイート
Qiita：30 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">VTuberになるための参考リンク集 <a href="https://t.co/NPKY5HDbBM">https://t.co/NPKY5HDbBM</a></p>&mdash; けもみみおーこく公式 (@kemomimi_oukoku) <a href="https://twitter.com/kemomimi_oukoku/status/1062249276439375872?ref_src=twsrc%5Etfw">2018年11月13日</a></blockquote>
Vtuberになるための情報を集めた記事。あまりプログラミングっぽくはないですが、多くの人が興味を持ちそうなテーマです。
<br/>
**4位**
Twitter：169 リツイート
Qiita：23 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">数独はスピン4の非局所イジング模型なので、横磁場の量子アニーリングで一瞬で解けるはずやろと思ってググってみたら、やっぱり試している人がいた<a href="https://t.co/m0a7Poe7zr">https://t.co/m0a7Poe7zr</a></p>&mdash; 橋本幸士 Koji Hashimoto (@hashimotostring) <a href="https://twitter.com/hashimotostring/status/1058678820977356800?ref_src=twsrc%5Etfw">2018年11月3日</a></blockquote>
「数独」をプログラミングで解いている記事。数独やったことないのでよくわかりませんが、凄いのかな。
<br/>
**5位**
Twitter：149 リツイート
Qiita：23 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">吹奏楽全国大会への道のりを平成1年～平成30年のデータで分析してみた <a href="https://t.co/UpjVTT5mz8">https://t.co/UpjVTT5mz8</a></p>&mdash; yuhkan (@yuhkan) <a href="https://twitter.com/yuhkan/status/1060152191506276352?ref_src=twsrc%5Etfw">2018年11月7日</a></blockquote>
僕の記事ですみません。
（ちなみにツイートしてくれてるのは知らない方）
<br/>
**6位**
Twitter：144 リツイート
Qiita：211 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">乱立する深層強化学習のアルゴリズムたちを、体系的に学べるようにまとめてみました。<br><br>深層強化学習アルゴリズムまとめ <a href="https://t.co/Vi5AHdD0yR">https://t.co/Vi5AHdD0yR</a> <a href="https://t.co/HZMOxqV0GV">pic.twitter.com/HZMOxqV0GV</a></p>&mdash; Shion Honda (@shion_honda) <a href="https://twitter.com/shion_honda/status/1059436226241945601?ref_src=twsrc%5Etfw">2018年11月5日</a></blockquote>
深層強化学習のアルゴリズムたちをまとめた記事みたいです。読んでないけど凄そうですね。
<br/>
**7位**
Twitter：120 リツイート
Qiita：63 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">書きました / VRChatでkawaiiムーブを極める - VRIK Override <a href="https://t.co/Ye9U2Iyqj5">https://t.co/Ye9U2Iyqj5</a></p>&mdash; よしたか (@TyounanMOTI) <a href="https://twitter.com/TyounanMOTI/status/1038036285468770304?ref_src=twsrc%5Etfw">2018年9月7日</a></blockquote>
VRChat関連記事です。こちらもVtuber記事同様プログラミングっぽくはないですが、楽しそう。
<br/>
**8位**
Twitter：117 リツイート
Qiita：838 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【全ての開発者が学ぶべき5つの言語】<br>1. Java<br>2. Python<br>3. JavaScript<br>4. C Programming<br>5. Scala<br><br>それぞれ、なぜその言語なのかという説明が記事でされているので、<br>詳細は記事を読んでみてください！<br>焦らず、一つの言語ずつ勉強していきましょう！<a href="https://t.co/oATtLPtzab">https://t.co/oATtLPtzab</a></p>&mdash; Progate@プログラミング学習 (@prog_8) <a href="https://twitter.com/prog_8/status/1060119769385525248?ref_src=twsrc%5Etfw">2018年11月7日</a></blockquote>
学ぶべき言語系の記事。個人的にはタイミングや環境で大きく変わると思うので強引に言い切る必要はないと思いますが、初心者の指標としては良いのかもですね。
<br/>
**9位**
Twitter：109 リツイート
Qiita：677 いいね
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">オブジェクト指向の入門記事を作ってみました。<br>どうかお手柔らかにご査収ください。<a href="https://t.co/RfJkg2GoO6">https://t.co/RfJkg2GoO6</a></p>&mdash; nrs (@nrslib) <a href="https://twitter.com/nrslib/status/1060297106953428992?ref_src=twsrc%5Etfw">2018年11月7日</a></blockquote>
オブジェクト指向入門記事。こちらも初心者向けの記事のようです。すごく長い。


# 良記事とダメ記事に偏ったか？
結果を見て感じたことをまとめます。大きく3つあります。

**①ダメ記事には偏る**
記事が公開停止されていたので上に載せてはいませんが、数だけで言うと、最近議論の対象になっていたヤバい記事が、実は最もリツイート数が多かったです。やはり、みんなにヤバさ・怖さを共有したいという思いがリツイートを呼び、大きな偏りを生んでいました。

**②エンジニア以外にウケる記事にも偏る**
一方で、良記事と言っていいのかはわかりませんが、難易度によらず、便利なもの・面白いものを作った記事が多く選ばれている印象も受けました。簡単に言うと**「エンジニア以外にもウケる記事」**でしょうか。Twitterはエンジニア以外が大半なので、一般向けにも楽しめる内容が拡散されるのは当然と言えば当然ですが。

**③Qiitaの「いいね」とTwitterの「リツイート」は比例しない**
面白かったのはここですかね。やはり**QiitaとTwitterはユーザ層が違うからか、「良い」とされるものが違う**ようです。各記事の全リツイートを合計したら結果は多少違うかもしれませんが、大枠は変わらないでしょう。

# あとがき
結果的に、そこまで有用なフィルターにはなりませんでしたが、**「大衆にウケる記事」という意味で参考程度には楽しめるものになったかな**と思います。

逆に言えば、「エンジニアにウケる情報」や、「正確な情報」を求めている人は、世間の「いいね」や「リツイート」などは気にせず、**小規模でも純粋なエンジニアが集まるコミュニティに入ったり信頼できる人をフォローするのが良いのでしょう。**幅と深さを両方求めるのはなかなか難しい気がするので。

ということで、みなさんトレンドなんて気にせず作りたいものを作りましょう。