はてなブックマークの破滅的人気コメントを表示する

# 何があったか
https://bookmark.hatenastaff.com/entry/yahoo_comment_api

はてなブックマークは、コメント表示改善の一環として、Yahoo! JAPANの「建設的コメント順位付けモデルAPI」を導入し、攻撃的であったり不謹慎であるなど穏当でないコメントが人気コメントに掲載される問題を抑制する取り組みを開始しました。

実は、公式の発表が知れ渡る前にAnonymousDiaryというサービスで話題になり、喧喧囂囂の大騒ぎとなったのです。

https://anond.hatelabo.jp/20210719114552

**誉れ高い増田市民としては、旧来の破滅的コメント順位を望みます。**

# Pythonによる解決
googleのcolabで作業してました。

- 記事の情報をAPIで入手
- 記事jsonからブクマした各ユーザの「コメント情報のURI」を生成する
- スター取得APIでコメントURIを指定し、スター数を算出
- 各コメントのスター数を出し、上位10個を表示

後述するjsonの概要を見るとイメージがつきやすいかもしれません。

```python
import json, re
import urllib.request, urllib.parse

'''
記事のjsonを取得。
'''
def getEntry(targetUrl):
  encodedUrl = urllib.parse.quote(targetUrl) # 記号を%でエスケープするやつ
  apiUrl = 'https://b.hatena.ne.jp/entry/jsonlite/?url=' + encodedUrl
  req = urllib.request.Request(apiUrl, method='GET')
  with urllib.request.urlopen(req) as res:
    return json.loads(res.read()) # 辞書型が返ってくるはず

# 2021/07/19 23:29 => 20210719
def makeDate(timestampString):
  m = re.match("^([0-9]+)/([0-9]+)/([0-9]+)" , timestampString)
  return "".join(m.groups())

'''
コメント情報を取得する。コメントに付いたスター情報を含む。
# bookmark: エントリー情報中の"bookmarks"
# template: ユーザIDとブクマ日(YYYYMMDD)が抜けたテンプレ
'''
def getComment(bookmark, template):
  # コメントのURIを生成する
  userId = bookmark['user']
  date = makeDate(bookmark['timestamp'])
  target = urllib.parse.quote(template.format(userId, date))
  # はてなスター取得API
  apiUrl = 'https://s.hatena.com/entry.json?uri=' + target
  req = urllib.request.Request(apiUrl, method='GET')
  with urllib.request.urlopen(req) as res:
    return json.loads(res.read())

''' 
試す
'''
# 「 https://b.hatena.ne.jp/{ユーザーID}/{コメントの日付(YYYYMMDD)}#bookmark-{エントリーID} 」
entry = getEntry('https://anond.hatelabo.jp/20210719114552') # 冒頭の記事を例にする
template = "https://b.hatena.ne.jp/{0}/{1}#bookmark-" + entry['eid']

# 同期処理なので、コメント数と比例して時間がかかる。(おそらく)
comments = []
for bookmark in entry['bookmarks']:
  if(not bookmark['comment']): # コメントが無いブクマは無視。通信を伴う同期処理で遅いので。
    continue
  comment = getComment(bookmark, template)
  if(len(comment['entries']) < 1):
    continue
  star = len(comment['entries'][0]['stars'])
  comments.append((bookmark['user'], bookmark['comment'], star)) # ("yourname", "it's a comment.", 5)

goodComments = sorted(comments, key=lambda x:x[2], reverse=True)[0:9]
print(goodComments)
```

# メモ
## APIについて
https://syncer.jp/hatebu-api-matome

- `http://s.hatena.com/entry.json?uri={ブコメのパーマリンク}`でスター数を取得。
- ただし、コメントは`http://b.hatena.ne.jp/{ユーザーID}/{コメントの日付(YYYYMMDD)}#bookmark-{エントリーID}`を指定する。

## entryのjson
```json
  {
    ...
    "bookmarks": [
      {
        "user": "editor_t",
        "tags": [],
        "comment": "",
        "timestamp": "2021/07/19 23:36"
      },
      {
        "timestamp": "2021/07/19 23:35",
        "comment": "",
        "user": "Ta-nishi",
        "tags": []
      }, ...
    ],
    "eid": "4705668973035540098"
  }
```

## コメントのjson
```json
  {
    "entries": [
      {
        "stars": [
          {
            "quote": "",
            "name": "korok_kuma3"
          },
          {
            "name": "kako-jun",
            "quote": ""
          }, ...
        ], 
        "can_comment": 0
      }
    ],
    "can_comment": 0
  }
```

## 参考URL
- https://syncer.jp/hatebu-api-matome APIについて。2015年の情報だが、よくまとまっている。
- http://developer.hatena.ne.jp/ja/documents/bookmark/apis/getinfo 記事の情報を取ってくるAPI。
- http://developer.hatena.ne.jp/ja/documents/star/apis/entry スター数取得に関するAPI。
- https://www.ituki-yu2.net/entry/Access-Control-Allow-Origin CORSの問題があり、jsでは完結しない。

# 免責
これがスパムとされたら規約違反なので、やってはいけない。
http://developer.hatena.ne.jp/license

# ちなみに
https://anond.hatelabo.jp/20210719114552 
の2021/07/20 03:58 時点でのブックマーク↓
https://b.hatena.ne.jp/entry/s/anond.hatelabo.jp/20210719114552

「本当の」人気コメントがこちら。(何かを間違えているので9個しか表示されませんでした。)

```
1. 320 ('mayumayu_nimolove', '人生で一番スターもらった/素晴らしいニュースをありがとうございます。増田さんの意見に同意です。私も職業柄興味があり、ここ数年間追い求めてまさに増田さんのおかげで解決しました。ありがとうござい増田。')
2. 157 ('usomegane', 'これには反対だわ。スター工作対策までは許容できたけど、コメントの内容の良し悪しはブクマカ間の相互批判や議論でユーザーが判断するべき。')
3. 127 ('unticrice', '人気コメントじゃなくて「人工知能による建設的な気配がするコメント」、略して人気コメントじゃねーか！')
4. 121 ('x100jp', 'さっき人気コメに載ってなかったという事は、非建設的ブコメと認定されたのか。僕は悲しい。（非建設的ブコメ）/\u3000文字数が必要な気がする。梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅')
5. 114 ('muchonov', 'こういうAIによる緩いモデレーション制御は、誹謗中傷や集団極性化の問題へのひとつの回答だと思うけど、そうやって「非建設的」コメントを排除したものを人気コメント一覧と呼ぶのが適切かどうかはまた別の議論')
6. 108 ('vlxst1224', 'まじだ何か注意書きが現れやがったぞ。スターを集められるかどうかは分からないが弾かれるか試してみるか。う●こ') 
7. 097 ('madooka', 'はてブの人気コメントの問題は、非建設的だからではなく攻撃性が高いからでは。薄目で見ると建設的であろうとはしている気がする') 
8. 076 ('AQM', '定礎／（追記）アーキテクト アース付きコンセント アームチェア アーリーアメリカンスタイル アール・ヌーボー 相決り アイランドキッチン 青色申告 赤さび 赤身 アカンサス アクリル板 アコーディオンドア 足場 足元灯')
9. 073 ('daydollarbotch', '鹿島しいコメントのテンションが竹ー中で、人力で選別するのもキャパ大林、も清水にスターを付ける人がいても分からない。大成を制する良いブコメをAIが選んでほしい。根拠はこちら http://ja.wikipedia.org/w/index.php?curid=57752')
```


そして、「建設的な」コメントがこちら。(こちらも9個までに揃えました。)
順位と表示順が一致する前提です。スター数が壊れてますが気にしません。

```
1. 16856 ('mayumayu_nimolove', '人生で一番スターもらった/素晴らしいニュースをありがとうございます。増田さんの意見に同意です。私も職業柄興味があり、ここ数年間追い求めてまさに増田さんのおかげで解決しました。ありがとうござい増田。')
2. 155 ('usomegane', 'これには反対だわ。スター工作対策までは許容できたけど、コメントの内容の良し悪しはブクマカ間の相互批判や議論でユーザーが判断するべき。')
3. 316 ('x100jp', 'さっき人気コメに載ってなかったという事は、非建設的ブコメと認定されたのか。僕は悲しい。（非建設的ブコメ）/\u3000文字数が必要な気がする。梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅梅')
4. 112 ('muchonov', 'こういうAIによる緩いモデレーション制御は、誹謗中傷や集団極性化の問題へのひとつの回答だと思うけど、そうやって「非建設的」コメントを排除したものを人気コメント一覧と呼ぶのが適切かどうかはまた別の議論')
5. 095 ('madooka', 'はてブの人気コメントの問題は、非建設的だからではなく攻撃性が高いからでは。薄目で見ると建設的であろうとはしている気がする') 
6. 106 ('vlxst1224', 'まじだ何か注意書きが現れやがったぞ。スターを集められるかどうかは分からないが弾かれるか試してみるか。う●こ') 
7. 071 ('daydollarbotch', '鹿島しいコメントのテンションが竹ー中で、人力で選別するのもキャパ大林、も清水にスターを付ける人がいても分からない。大成を制する良いブコメをAIが選んでほしい。根拠はこちら http://ja.wikipedia.org/w/index.php?curid=57752')
8. 062 ('srgy', '大喜利勢にとっての冬の時代到来…？　/　(追記)「ルックバック」のブクマ数1793時点でのBingキャッシュ https://archive.vn/tzXlA　現在の同エントリの「人気コメント」は、ここから3つ排除されてる…')
9. 076 ('AQM', '定礎／（追記）アーキテクト アース付きコンセント アームチェア アーリーアメリカンスタイル アール・ヌーボー 相決り アイランドキッチン 青色申告 赤さび 赤身 アカンサス アクリル板 アコーディオンドア 足場 足元灯')
```

### キレイに俺のコメントだけ除外されてます

はてなさん...どうして...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619160/7c5b7270-e7fc-6363-68b2-f1ce633df343.png)
それが「はてな」ってことなんですか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619160/c4bf9bfd-6f3a-33e3-48e2-e60c528b61cb.png)

.
.
.
でも確かにくだらなかったのでアルゴリズムは正しく動いてますね。
やってみて思ったんですが、割とどうでもいいですね。