日記

のみろぐ

主に競プロ日記です

一人暮らしの風邪は詰み

風邪を引いた。つらい。

でもアドベントカレンダーは書きたい(わがまま。かわいいかよ)

やること

↓これをつくります

僕「お腹すいた」

ロボ「XXを食べると風邪にいいんだよ!!!!」

僕「へー…」

つまり、かぜ引いた時に何食べればいいかをオススメしてくれるやつを作る

流れ

  1. yahooショッピングで「風邪 食べ物」を検索
  2. 検索結果から食べ物の名前を抜き出す
  3. カウント数が多かった食べ物を食べる

1. 検索結果の取得

準備するもの

  • yahooショッピング検索API

    • 使うにはアプリ登録をしてアプリIDをゲットする必要があります。Yahooアカウントがあれば3秒でもらえます(ここ)
  • Pythonのrequestsモジュール

    • pip install requestsで入手

やること

  1. GETリクエストを送って検索結果のXMLを手に入れる。以上!

コード

import requests

def search(keyword):
        url = 'https://shopping.yahooapis.jp/ShoppingWebService/V1/itemSearch'
        url += '?appid=' + 'ここにアプリIDを入れる' # アプリのID
        url += '&query=' + keyword # 検索ワード
        url += '&hits=50' # 取得件数(最大50件)
        response = requests.get(url.encode('utf-8')) # utf-8にエンコードしないといけない
        return response.text

2. 文章から単語を抜き出す

準備するもの

  • MeCab

    • 文章を品詞ごとに分けてくれるやつ。商品説明文から名詞を抜き出すのに使う。
    • brew install mecabで入手
  • MeCab辞書

    • なんか欲しいらしい。
    • brew install mecab-ipadicで入手
  • PythonMeCabを使うためのモジュール

    • pip install mecab-python3で入手

やること

  1. XMLから全ての商品説明文を抜き出す
  2. 抜き出した商品説明文の名詞をリストに格納。以上!

コード

import MeCab
import xml.etree.ElementTree as ET

# XMLから全ての商品説明文を取得する
descriptions = []
def get_descriptions(parent):
    for child in parent:
        if child.tag == "{urn:yahoo:jp:itemSearch}Description" and child.text != None: # なんか{urn:yahoo:jp:itemSearch}が必要みたい
            descriptions.append(child.text)
        get_descriptions(child)

# 文章から名詞を抜き出し、それをリストにして返す
def get_words_list(s):
    mecab = MeCab.Tagger ("-Ochasen")
    node = mecab.parseToNode(s)

    foods = []
    while node:
        if node.feature.split(',')[0] == '名詞' and node.surface >  '~': # 名詞抜き出し and 雑に記号を排除
            foods.append(node.surface)
        node = node.next
    
    return foods

# XMLを渡すと、重複ありの名詞単語リストが返される
def get_foods(xml_txt):
    root = ET.fromstring(xml_txt) # XMLの根
    get_descriptions(root) # XMLから説明文を抜き出す

    foods = []
    for description in descriptions:
        foods += get_words_list(description)
    
    return foods

3. 食べる

準備するもの

  • 特にない

やること

  1. 重複ありの単語リストから、出現頻度の高い順に表示する。以上!

    1. TF-IDFとかの方がいいんだろうけど面倒なので素直にカウントしました。

コード

import collections

def get_result(foods):
        most = collections.Counter(foods).most_common()
        result = '風邪を引いた時は\n'
        for i in range(5):
                result += '「' + most[i][0] + '」\n'
        result += 'を食べるといいよ!'
        return result

結果

風邪を引いた時は
「年」
「風邪」
「食」
「食べ物」
「日」
を食べるといいよ!
  • へー...

コード全体

import sys
import requests
import MeCab
import xml.etree.ElementTree as ET
import collections

# yahoo検索結果のXMLを取得
def search(keyword):
    url = 'https://shopping.yahooapis.jp/ShoppingWebService/V1/itemSearch'
    url += '?appid=' + 'アプリID' # アプリのID
    url += '&query=' + keyword # 検索ワード
    url += '&hits=50' # 取得件数(最大50件)
    response = requests.get(url.encode('utf-8')) # utf-8にエンコードしないといけない
    return response.text

# XMLから全ての商品説明文を取得する
descriptions = []
def get_descriptions(parent):
    for child in parent:
        if child.tag == "{urn:yahoo:jp:itemSearch}Description" and child.text != None: # なんか{urn:yahoo:jp:itemSearch}が必要みたい
            descriptions.append(child.text)
        get_descriptions(child)

# 文章から名詞を抜き出し、それをリストにして返す
def get_words_list(s):
    mecab = MeCab.Tagger ("-Ochasen")
    node = mecab.parseToNode(s)

    foods = []
    while node:
        if node.feature.split(',')[0] == '名詞' and node.surface >  '~': # 名詞抜き出し and 雑に記号を排除
            foods.append(node.surface)
        node = node.next
    
    return foods

# XMLを渡すと、重複ありの名詞単語リストが返される
def get_foods(xml_txt):
    root = ET.fromstring(xml_txt) # XMLの根
    get_descriptions(root) # XMLから説明文を抜き出す

    foods = []
    for description in descriptions:
        foods += get_words_list(description)
    
    return foods

def get_result(foods):
    most = collections.Counter(foods).most_common()
    result = '風邪を引いた時は\n'
    for i in range(5):
        result += '「' + most[i][0] + '」\n'
    result += 'を食べるといいよ!'
    return result

# 1. 検索結果を取得
xml_txt = search('風邪 食べ物')

# 2. 商品説明文の単語を取得
foods = get_foods(xml_txt)

# 3. これを食べます
result = get_result(foods)
print(result)