Qiita API v2 でPythonista(3) の記事を取得する（Pythonista3 Advent Calendar 2022 前夜祭0日目）


この記事は、[Pythonista3 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/pythonista3) の00日目（前夜祭）の記事です。

https://qiita.com/advent-calendar/2022/pythonista3

一方的な偏った目線で、Pythonista3 を紹介していきます。

ほぼ毎日iPhone（Pythonista3）で、コーディングをしている者です。よろしくお願いします。

以下、私の2022年12月時点の環境です。

```
--- SYSTEM INFORMATION ---
**System Information**

* Pythonista 3.3 (330025), Default interpreter 3.6.1
* iOS 16.1.1, model iPhone12,1, resolution (portrait) 828.0 x 1792.0 @ 2.0
```

他の環境(iPad や端末の種類、iOS のバージョン違い)では、意図としない挙動(エラーになる)なる場合もあります。ご了承ください。

ちなみに、`model iPhone12,1` は、iPhone11 です。

## Pythonista3 Advent Calendar 2022 前夜祭

いよいよ、明日から[Qiita Advent Calendar 2022](https://qiita.com/advent-calendar/2022) がはじまりますね！

https://qiita.com/advent-calendar/2022

つまり、[Pythonista3 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/pythonista3) もはじまります。

25日間全記事が私ですね。よろしくお願いします。

11月頃のAdvent Calendar 案内リリース前後にPythonista3 で、[Core ML](https://developer.apple.com/jp/documentation/coreml/) を使った[Vision](https://developer.apple.com/documentation/vision?language=objc) にて顔認識が成功してしまいまして。。。

それに気をよくした勢いでAdvent Calendar に登録をしてしまいました。という経緯でございます。

結果、このようにもりもりと、記事を量産している次第であります。

![img221130_005654.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/5c30b645-e467-32fa-c0fe-6d411b1166da.gif)


### モチベーションあげてこー

Pythonista3 の面白さ楽しさを紹介したい思いは強いのです。

が、25記事。。。年末。。。

Advent Calendar なのだからクリスマス・年末に向けているので当たり前なのですが。。。

あかん、もう、12月が来てしまう。。。

本来はAdvent Calendar 本編の記事を進めなくてはいけないのは重々承知の上なのですが、なぜか前夜祭として前日に1記事追加している始末。。。

みんな！！オラに元気を可能な限りわけてくれ！たのむ！

### みんなの元気、、、？

Qiita の登録もAdvent Calendar 登録を機におこないました。

なのでまだ、登録ユーザー側のQiita は全く理解していません。

このギリギリのタイミングで、改めて投稿の方法などをみている時に、API の存在に気がつきました。

https://qiita.com/api/v2/docs#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC

「そうだ、Qiita のPythonista3 の記事をAPI の力で集めてみよう」

まだ、本格的に記事のアップや公開までもしていないのに、いらん事を思いついてしまいました。

思い立ったが吉日。どうにもやめられない性分なのです。

## Qiita API v2 から、`Pythonista3` タグ記事を集める

先にお断りをしておきます。

普段はAPI で何かする。とか全くしておらず、今回は雰囲気でなんとかしています。

とりあえず「適当に作ったらうごいたあああああああ！！」状態でございます。色々と教えてください。

こちらと睨めっこし、進めました。

[GET /api/v2/tags | Qiita API v2ドキュメント - Qiita:Developer](https://qiita.com/api/v2/docs#%E3%82%BF%E3%82%B0)

https://qiita.com/api/v2/docs#%E3%82%BF%E3%82%B0

以下、コードの全貌です（恥ずかしい）

```qiitaAPIv2.py
from pathlib import Path
import requests


def get_accesstoken():
  _path = Path().home() / 'Documents' / 'qiitaAccessToken.txt'
  return _path.read_text().replace('\n', '') if _path.exists() else None


TOKEN = get_accesstoken()
HEADERS = {'Authorization': f'Bearer {TOKEN}'} if TOKEN else None
URL = 'https://qiita.com/api/v2/tags/'


def get_tag_items_count(tag_name):
  url = URL + tag_name
  r = requests.get(url, headers=HEADERS)
  text_json = r.json()
  return int(text_json['items_count'])  # int 追い掛け


def get_item_list(tag_name, items_count):
  item_list = []
  url = URL + tag_name + '/items'
  count = (items_count // 100) + 1  # 100記事以上あれば
  for c in range(count):
    params = {
      'page': f'{c + 1}',
      'per_page': '100',
    }
    r = requests.get(url, params=params, headers=HEADERS)
    items_json = r.json()
    for item in items_json:
      item_list.append([
        item['title'],
        item['url'],
        item['user']['id'],
        item['created_at'],
      ])
  return item_list


def get_qiita():
  pool_list = []
  tags = ['Pythonista3', 'Pythonista']
  for tag in tags:
    count = get_tag_items_count(tag)
    item_list = get_item_list(tag, count)
    pool_list.extend(item_list)
  return list(map(list, set(map(tuple, pool_list))))  # 重複しているものを削除


def out_md_format(tag_item_list):
  out_txt = ''
  for item in tag_item_list:
    # 力技
    out_txt += f'- [{item[0]}]({item[1]})\n  - {item[2]}\n  - {item[3]}\n\n'
  print(out_txt)
  print(f'\n{len(tag_item_list)} 記事')


if __name__ == '__main__':
  qiita_list = get_qiita()
  l = sorted(qiita_list, key=lambda x: x[3], reverse=True)  # 作成日でソート
  out_md_format(l)

```

取得まで少し時間がかかります。

![img221130_012543.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/f2c01da2-691c-4aa8-30ca-90e532568280.gif)


なんと、ざっくり取得して`183` もの記事があるのですね！


![img221130_150819.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/f71ebb54-1228-e6eb-be3a-68a6db9e2d5c.png)



最新の記事は、take_me さんの[【Pythonista3】ActivityIndicatorの使い方 - Qiita](https://qiita.com/take_me/items/1c2ad512ec3ee9a8bdf4) でございました！

https://qiita.com/take_me/items/1c2ad512ec3ee9a8bdf4

記事の内容がなかなか攻めていて、`@ui.in_background` のことも紹介されており、最高ですよね！

ActivityIndicator は、過去使ってみようと思いつつ実際やっていなかったので今度試してみたいものです☺️

### （かんたんな）コード説明

後で判明しましたが、access token は必須ではないです。トークンがあれば試行回数が増える感じでした。

このコードを試す程度でしたら、access token は不要ですね。

今回は、access token なくても動くようにしています。

#### `requests` モジュール

Pythonista3 にデフォルトで入っているので使いました。完全に雰囲気で使ってます！

記事全部取得ができず（100記事まで？）

- 何記事あるか確認
- 記事数に合わせて取得

そのたびに、`requests.get` しております。こんなに`requests.get` って呼び出すのかしらん？と、モヤっとしていますです。

また、今回検索tag が`'Pythonista3'`, `'Pythonista'` の2つあるので、上記の流れを2回行っていることになります。

#### get したもの

返ってきたjson から、タイトル・URL ・ユーザー名・作成日を`list` で突っ込んでいます。本来は`dic` なのかもしれませんね。

```py
items_json = r.json()

item_list = []

for item in items_json:
  item_list.append([
    item['title'],
    item['url'],
    item['user']['id'],
    item['created_at'],
  ])
```

Pythonista3 の内容ではなく、`Pythonista` （Python を書く人）のことも、持ってきてるかもしれませんが、そのあたりは無視してます！

#### それなりに整える

`Pythonista` と`Pythonista3` 両方で、tag 登録の可能性もあるので、重複を削除:

```py
list(map(list, set(map(tuple, pool_list))))
```

https://qiita.com/uuuno/items/b714d84ca2edbf16ea19

作成日で並び替え:

```py
sorted(qiita_list, key=lambda x: x[3], reverse=True)
```

https://qiita.com/t_kanno/items/13dd226e70d080159d97

自分で`list` 作って格納しているので、インデックス指定の力技です。

#### 出力

100を越えるリンク集を記事として公開すると、スパム扱いされそうなので自重しますが、自分用にMarkdown 形式に:

```py
out_txt += f'- [{item[0]}]({item[1]})\n  - {item[2]}\n  - {item[3]}\n\n'
```

`print` 出力すると、Pythonista3 のconsole ではハイパーリンク認識をしてくれるので、URL をタップするとPythonista3 内部のブラウザが立ち上がります。


![img221130_151040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/d6a73ad2-c23b-9951-f8b9-5420e6b9f373.png)



Pythonista3 の内部処理を細かく確認してないですが、多分UIWebView を使っているのではないだろうか、、、

[UIWebViewを使用するAppのアップデート期限の延長 - 最新ニュース - Apple Developer](https://developer.apple.com/jp/news/?id=edwud51q)

https://developer.apple.com/jp/news/?id=edwud51q

ここらへんの、ドキドキ感があります。

### API 登録

実際のところAPI 登録する必要なかったかもなのですが、私は登録したので、その流れを紹介していきます。

- 右上の自身のアカウントアイコンをタップ
- `[設定]` をタップ


![img221130_171137.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/2c34a9c4-3fef-4579-0a6b-fa503846b3a1.png)



- `[アプリケーション]` をタップ

![img221130_171534.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/9d8a0150-8950-41ea-fd1a-14e5ba9cc7ae.png)


- 下の方にスクロール
- `新しくトークンを発行する` をタップ

![img221130_171654.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/e14db915-005d-d360-a9f9-cc7d5cde6e49.png)




- `アクセストークンの説明` に良きな内容を入力
  - 今回は`Pythonista3TagSearch`
- `read_qiita` を選択
- `[発行する]` をタップ


![img221130_171806.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/624a68e9-53bd-a6e6-677e-5f706840aa4c.png)



- トークン文字列が出ているのでコピー


![img221130_172013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953777/3dbf4c71-55a0-8b06-28dc-b39135bd0bc8.png)




（私は）コピーした文字列を、ScriptLibrary 直下に`qiitaAccessToken.txt` として保存しました。

## Advent Calendar 楽しみー

明日から始まるAdvent Calendar 楽しみですね！

私もQiita にあるPythonista3 の記事読んでモチベーションあげて、Pythonista3 Advent Calendar 2022 頑張りたいと思います。

この記事のように、所々にスクリーンショットやGIF でのキャプチャを入れて、なるべく楽しげにやっていきます。

もしかすると、そこら辺の読み込みで表示遅くなっていたらすみません。。。




ここまで、読んでいただきありがとうございました。

## せんでん

### Discord

Pythonista3 の日本語コミュニティーがあります。みなさん優しくて、わからないところも親身に教えてくれるのでこの機会に覗いてみてください。

https://t.co/0IOW2hn1VC

### 書籍

iPhone/iPad でプログラミングする最強の本。

- [Python や Jupyter で iPhone/iPad 先端機能を簡単･自由にプログラミング！「活用篇」：hirax](https://techbookfest.org/product/1WiyV4LEev3f4YrzesRKWV?productVariantID=axX32srsSgtLtZWUtjkj99)

https://techbookfest.org/product/1WiyV4LEev3f4YrzesRKWV?productVariantID=axX32srsSgtLtZWUtjkj99

- [Python や Jupyter で iPhone/iPad 先端機能を簡単･自由にプログラミング！「土台篇」：hirax](https://techbookfest.org/product/wTZTyeibm5GQ5XgdfMrEBV?productVariantID=kRDmN1udbEYZUWbETdwL8r)

https://techbookfest.org/product/wTZTyeibm5GQ5XgdfMrEBV?productVariantID=kRDmN1udbEYZUWbETdwL8r

### その他

- サンプルコード

[Pythonista3 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/pythonista3) でのコードをまとめているリポジトリがあります。

コードのエラーや変なところや改善点など。ご指摘やPR お待ちしておりますー

https://github.com/pome-ta/Pythonista3AdventCalendar2022sampleCode

- Twitter

なんしかガチャガチャしていますが、お気兼ねなくお声がけくださいませー

https://twitter.com/pome_ta93

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やれるか、やれないか。ではなく、やるんだけども、紹介説明することは尽きないと思うけど、締め切り守れるか？って話よ！（クズ）<br><br>Pythonista3 Advent Calendar 2022 <a href="https://t.co/JKUxA525Pt">https://t.co/JKUxA525Pt</a> <a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a></p>&mdash; pome-ta (@pome_ta93) <a href="https://twitter.com/pome_ta93/status/1588570697777152006?ref_src=twsrc%5Etfw">November 4, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

- GitHub

基本的にGitHub にコードをあげているので、何にハマって何を実装しているのか観測できると思います。

https://github.com/pome-ta