gooAPIでキーワード抽出のプログラムを作ってみた

##はじめに
皆さんはじめまして。
今回はPython3とgooAPIを使ったキーワード抽出のプログラムを作ってみました。このプログラムは[@gossy5454さんのCOTOHAAPIをPythonで...](https://qiita.com/gossy5454/items/83072418fb0c5f3e269f)のプログラムを流用してgooAPIを使ってみたいなと思い作りました。

##[goo キーワード抽出APIについて](https://labs.goo.ne.jp/api/jp/keyword-extraction/)
タイトルと本文からなる文書から、人名、地名、組織など文書を特徴付けるキーワードを抽出できます。

パラメータで
・タイトル
・本文
・最大出力キーワード数
・注目固有表現（組織名、人名、地名）
が指定できます。

##gooAPIの利用について
gooAPIは無料で使用できます。使用のためについては[API利用方法](https://labs.goo.ne.jp/apiusage/)を参考にしてください（完了したときに表示されるアプリケーションIDはコピーし忘れると再取得しなくてはいけないので保存したほうがいいです！！）

##プログラム
このプログラムは「はじめに」にも書いてある通り[この記事](https://qiita.com/gossy5454/items/83072418fb0c5f3e269f)を参考にしています。なので事前準備は上記のページを参考にしてください。
言語はPython3です。


```python3:gooapi.py

# -*- coding:utf-8 -*-

import os
import urllib.request
import json
import configparser
import codecs



# GOO API操作用クラス
class GooApi:
    # 初期化
    def __init__(self, request_url):
        self.request_url = request_url
   
    # キーワード抽出API

    def keyword(self, id, title ,body, max_num, focus):
        # キーワード抽出API URL指定
        url = self.request_url
                
        # ヘッダ指定
        headers={
            "Content-type": "application/json",
        }
        
        # リクエストボディ指定
        data = {
            "app_id": id,
            "title": title,
            "body": body,
            "max_num": max_num,
            "focus": focus
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        print(req)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        
        except:
            print ("<Error> " + e.reason)

        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得 
        return res_body



if __name__ == '__main__':
    # ソースファイルの場所取得
    APP_ROOT = os.path.dirname(os.path.abspath('__file__')) + "/"

    # 設定値取得
    config = configparser.ConfigParser()
    config.read(APP_ROOT + "config.ini")
    APPLICATION_ID = config.get("Goo API", "Application id")
    REQUEST_URL = config.get("Goo API", "Request URL")
    

    # goo APIインスタンス生成
    goo_api = GooApi(REQUEST_URL)

    # 文を直接打ち込みたいとき
    sentence = "解析対象"
    
    #テキストファイルを読み込見たいとき
    text = open("解析対象.txt", "r", encoding="utf-8").read().replace('\n','')
    
    #タイトル設定
    title = "タイトル"
   
   
    # 構文解析API実行
    result = goo_api.keyword(APPLICATION_ID,title,text,10,"ORG")

    #def keyword(self, id, title, body, max_num, focus)
    #title:文のタイトル(省略する場合"")
    #body:解析したい対象(sentence:入力文から　text:テキストファイルから)
    #max_num:最大キーワード抽出数(最大10まで　それ以上を入力すると10個で固定です)
    #focus:注目してほしい固有表現
    #      ・ORG(組織名)
    #      ・PSN(人名)
    #      ・LOC(地名)
    #      以上ののうち一つを指定できます。上記以外の種別指定時は、すべての種別を同等に扱います。(省略する場合"")


    # 出力結果を見やすく整形
    result_formated = json.dumps(result, indent=4, separators=(',', ': '))
    print (codecs.decode(result_formated, 'unicode-escape'))
```

```config:config.ini

[Goo API]
Request URL:  https://labs.goo.ne.jp/api/keyword
Application id:  取得したアプリケーションID
```
こんな感じになってます。

##実行してみた
上記2つのプログラムを同一上のディレクトリおき、そのディレクトリ上で

```
python gooapi.py
```
というコマンドを打つと実行できます。

ここではテキストファイルを指定して実行してみます

```text:sample.txt

【MLB】選手が涙した少女への打球直撃　ネット拡大へ議論活発化、他球団選手は「100％支持」


アクシデントを受けて議論活発化「アスレチックスの選手たちは防護ネット拡大を支持」

　5月29日（日本時間30日）にヒューストンの「ミニッツ・メイド・パーク」で行われたアストロズ-カブス戦で、痛烈なライナーのファウルボールが観戦中の4歳の少女に直撃するというアクシデントがあった。
これを受け、選手たちも防護ネット拡大を望む声を上げたと米メディアが報じている。
この試合では、ファウルを打ったカブスのアルバート・アルモラJr.内野手がその場で座り込んで涙を流すシーンがあったが、メジャーリーガーも観客が負傷するリスクが少しでも軽減されることを願っているようだ。

　米メディア「NBCスポーツ」では、「アスレチックスの選手たちはMLBの球場での防護ネット拡大を支持する」とのタイトルで記事を掲載。
ヒューストンでの事故を受けて、ネットを拡大すべきかどうかの議論が活発に行われるようになったと言及している。

　アストロズ-カブス戦では、4回無死一、二塁の場面でアルモラJr.が打った三塁方向への痛烈なライナーが、客席の少女に直撃した。少女はその後、病院に搬送されたが、アルモラJr.はその場で座り込んで涙。
同僚のヘイワードやバエス、マドン監督に慰められ、試合後には憔悴した様子で「今は祈るしかない」などと語っていた。

　記事では、この打球が115マイル（約185キロ）だったと言及。
現在、メジャーの全ての球場では両ダグアウトまではネットが設置されていると紹介しているが、これだけの痛烈な打球が客席に飛び込む可能性がある中、選手はそれでは十分ではないと考えているようだ。「あのような出来事は絶対起こってほしくない」「僕たちが求めているのは安全性」
　アスレチックスのチャド・ピンダー外野手は特集の中で「ファウルポールまでネットを設置することに大賛成だよ。
球団やリーグが安全のための予防措置を増やすための、いかなる策にも100％支持するね。なぜなら、あのような出来事は絶対起こってほしくはないんだから」とコメント。内野はすべてネットで覆われるべきだと主張している。

　さらに、昨季29本塁打を放った強打者のマット・オルソン内野手も「彼ら（球団やMLB）がファンの球場での時間をこれまで通りの（素晴らしい）ままにしようとしているのは理解している。
しかし、あの時の様に子供に直撃してしまったり、年配のファンや障害を抱えているファンは十分に素早く動けない状況なのだから、僕の気持ちとしてはネット拡大（を賛成する側）に傾むことになるだろうね」と証言。
185キロもの打球は避けられない人がいて当たり前で、事故防止のためにネット拡大には賛成との意見だ。

　さらに、記事ではスティーブン・ピスコッティ外野手が「ファンの安全が最優先だからね。投手たちは、これまでにないくらいの速球を投げるようになっているし、打者たちもこれまでにないほどの速い打球を放っているんだし」と話し、ラモン・ラウレアーノ外野手も「僕たちが求めているのは安全性。それは良いことだと思うんだ。誰かの人生を救えたり、怪我を最小限に留められることになれば、素晴らしいことだと思うよ」と指摘。
何よりも優先されるべきなのはファンの安全だとの見方だ。

　米メディアからもネットを拡大すべきだとの声が多く上がる一方で、“反対派”の人も中にはいるという。選手たちがこれだけ強く観客の安全の確保を望んでいる状況で、ネット拡大への流れは加速してもおかしくないが、果たしてどうなるだろうか。

```
ちょっと見にくいですがこのファイルを指定して、
title:ネット
max_num:10
focus:PSN(人名)
として実行してみます。

```
<urllib.request.Request object at 0x7f166c8d1ba8>
{
    "request_id": "labs.goo.ne.jp	1559901024	0",
    "focus": "PSN",
    "keywords": [
        {
            "アルモラ": 0.5702
        },
        {
            "マドン": 0.544
        },
        {
            "アスレチックス": 0.5079
        },
        {
            "チャド・ピンダー": 0.4393
        },
        {
            "MLB": 0.3386
        },
        {
            "防護ネット拡大": 0.3386
        },
        {
            "マット・オルソン": 0.3345
        },
        {
            "米": 0.3259
        },
        {
            "スティーブン・ピスコッティ": 0.256
        },
        {
            "議論活発化": 0.2501
        }
    ]
}
```

このように出力されます。PSNをfocusに指定したため選手の名前が多く抽出されており、問題となっているネット問題のことも抽出できました。

よかったら使ってみてください！！