質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Mecab

Mecabは、オープンソースの形態素解析エンジンです。 言語、辞書、コーパスに依存しない汎用的な設計を基本方針としています。 Mecabの由来は、開発者の好物である和布蕪(めかぶ)から名づけられました。

Q&A

0回答

1397閲覧

デプロイ時に起こる[ifs] no such file or directory: /usr/local/etc/mecabrcを解決したい

a2c6201

総合スコア0

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Mecab

Mecabは、オープンソースの形態素解析エンジンです。 言語、辞書、コーパスに依存しない汎用的な設計を基本方針としています。 Mecabの由来は、開発者の好物である和布蕪(めかぶ)から名づけられました。

0グッド

0クリップ

投稿2022/11/06 03:11

編集2022/11/06 03:47

前提・実現したいこと

初心者です。
Flaskを使って以下のようなWebアプリを作成しています。

  • TwitterAPIとFasttextを使って、過去Tweetを分析、ジャンル分けを行う
  • ツイート文をmecabによって分かち書きしたものを分析
  • デプロイしたWebアプリ

ローカル環境では問題なく動作しました。
Render.comを使ってデプロイしたところ、以下のエラーログが発生しました。
アプリを開発して、デプロイするのはこれが初めてです。

発生している問題・エラーログ

Nov 6 10:56:35 AM   [2022-11-06 01:56:35,050] ERROR in app: Exception on /result [POST] Nov 6 10:56:35 AM Traceback (most recent call last): Nov 6 10:56:35 AM File "/opt/render/project/src/.venv/lib/python3.7/site-packages/MeCab/__init__.py", line 133, in __init__ Nov 6 10:56:35 AM super(Tagger, self).__init__(args) Nov 6 10:56:35 AM RuntimeError Nov 6 10:56:35 AM Nov 6 10:56:35 AM The above exception was the direct cause of the following exception: Nov 6 10:56:35 AM Nov 6 10:56:35 AM Traceback (most recent call last): Nov 6 10:56:35 AM File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 2525, in wsgi_app Nov 6 10:56:35 AM response = self.full_dispatch_request() Nov 6 10:56:35 AM File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 1822, in full_dispatch_request Nov 6 10:56:35 AM rv = self.handle_user_exception(e) Nov 6 10:56:35 AM File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 1820, in full_dispatch_request Nov 6 10:56:35 AM rv = self.dispatch_request() Nov 6 10:56:35 AM File "/opt/render/project/src/.venv/lib/python3.7/site-packages/flask/app.py", line 1796, in dispatch_request Nov 6 10:56:35 AM return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) Nov 6 10:56:35 AM File "/opt/render/project/src/main.py", line 135, in result Nov 6 10:56:35 AM results = separate_tweet(tweets) Nov 6 10:56:35 AM File "/opt/render/project/src/main.py", line 44, in separate_tweet Nov 6 10:56:35 AM tagger = MeCab.Tagger('-Owakati') Nov 6 10:56:35 AM File "/opt/render/project/src/.venv/lib/python3.7/site-packages/MeCab/__init__.py", line 135, in __init__ Nov 6 10:56:35 AM raise RuntimeError(error_info(rawargs)) from ee Nov 6 10:56:35 AM RuntimeError: Nov 6 10:56:35 AM ---------------------------------------------------------- Nov 6 10:56:35 AM Nov 6 10:56:35 AM Failed initializing MeCab. Please see the README for possible solutions: Nov 6 10:56:35 AM Nov 6 10:56:35 AM https://github.com/SamuraiT/mecab-python3#common-issues Nov 6 10:56:35 AM Nov 6 10:56:35 AM If you are still having trouble, please file an issue here, and include the Nov 6 10:56:35 AM ERROR DETAILS below: Nov 6 10:56:35 AM Nov 6 10:56:35 AM https://github.com/SamuraiT/mecab-python3/issues Nov 6 10:56:35 AM Nov 6 10:56:35 AM issueを英語で書く必要はありません。 Nov 6 10:56:35 AM Nov 6 10:56:35 AM ------------------- ERROR DETAILS ------------------------ Nov 6 10:56:35 AM arguments: -Owakati Nov 6 10:56:35 AM [ifs] no such file or directory: /usr/local/etc/mecabrc Nov 6 10:56:35 AM ---------------------------------------------------------- Nov 6 10:56:35 AM Nov 6 10:56:35 AM 127.0.0.1 - - [06/Nov/2022:01:56:35 +0000] "POST /result HTTP/1.1" 500 265 "https://categorize-tweets.onrender.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"

該当のソースコード

Python

1from os import remove 2import re, json 3from crypt import methods 4from random import choice 5from glob import glob 6from flask import Flask, render_template, request, url_for 7import tweepy 8import fasttext as ft 9import MeCab 10import config 11 12COUNT = 700 # ツイート取得上限数 13model = ft.load_model('./model-1.bin') # 分類器 14 15# flask初期設定 16app = Flask(__name__) 17 18 19# 指定したユーザーのツイートを取得 20def get_tweet(id): 21 api = config.authTwitter() # config.pyを使ってAPI認証 22 tweets = [ 23 tweet 24 for tweet in tweepy.Cursor(api.user_timeline, screen_name=id).items(COUNT) 25 if list(tweet.text)[0] != '@' # リプライを除外 26 ] 27 return tweets 28 29 30# 正規表現を使ってツイートから不要な情報を削除 31def format_text(text): 32 text=re.sub(r'https?://[\w/:%#\$&\?\(\)~\.=\+\-…]+', "", text) # 外部リンクURL 33 text=re.sub(r'@[\w/:%#\$&\?\(\)~\.=\+\-…]+', "", text) # リツイート元のユーザーID 34 text=re.sub(r'\', "", text) 35 text=re.sub(r'/', "", text) 36 text=re.sub(r'RT', "", text) 37 text=re.sub(r'\n', " ", text) # 改行文字 38 return text 39 40 41# 文書を分かち書きし単語単位に分割 42def separate_tweet(tweets): 43 results = [] 44 tagger = MeCab.Tagger('-Owakati') 45 46 for tweet in tweets: 47 content = format_text(tweet.text) 48 wakati = tagger.parse(content) 49 results.append(wakati) 50 return results 51 52 53# ツイートを学習モデルに分類させて辞書に格納 54def categorize(results, raw_tweets): 55 print('取得ツイート'+str(len(results))+'件') 56 category_dic = {} 57 # ツイートをカテゴリに分類し、カテゴリごとのツイート数をカウント 58 for result in results: 59 raw_tweet = raw_tweets[results.index(result)] # ツイート原文を取得 60 result = result.replace('\n', ' ') 61 ret = model.predict(result) # ツイートをカテゴリ別に分類 62 cname = ret[0][0].replace('__label__', '') 63 # カテゴリ名をkeyに、ツイート原文をvalueとして辞書に格納 64 category_dic.setdefault(cname, []).append(raw_tweet.text) 65 return category_dic 66 67 68# 辞書をもとに分類されたツイートとその割合をjsonファイルに書き込み 69def get_json(dic, results, id): 70 categorydic = {} 71 for key in dic: 72 tweet_num = len(dic[key]) # カテゴリごとのツイート数 73 ratio = tweet_num / len(results) * 100 74 ratio = round(ratio, 1) 75 categorydic[key] = {} 76 categorydic[key]['ratio'] = ratio 77 categorydic[key]['content'] = dic[key] 78 with open('./json_dir/categorized-'+id+'.json', 'w') as f: 79 json.dump(categorydic, f, ensure_ascii=False, indent=2) 80 81 82def get_result_data(id): 83 """result画面で使う辞書型データを作成する関数 84 分類された整形前のツイートから一件のツイートをランダム抽出し辞書に格納 85 """ 86 with open('./json_dir/categorized-'+id+'.json', 'r') as j: 87 json_data = json.load(j) 88 for key in json_data: 89 json_data[key]['content'] = choice(json_data[key]['content']) 90 json_data[key] = [json_data[key]['ratio'], json_data[key]['content']] 91 return json_data 92 93 94def get_detail_data(category): 95 """detail画面で使うデータを作成する関数 96 97 jsonファイルから'ratio'キーの要素を削除し 98 指定されたカテゴリーのツイートを格納した辞書を作成 99 """ 100 detail_data = [] 101 file = glob('./json_dir/*.json') 102 with open(file[0], 'r') as j: 103 json_data = json.load(j) 104 for key in json_data: 105 del json_data[key]['ratio'] 106 detail_data = json_data[category]['content'] 107 return detail_data 108 109 110@app.route('/') 111def index(): 112 # jsonディレクトリ内のファイルを削除 113 json_files = glob('json_dir/*.json') 114 if json_files: 115 for file in json_files: 116 remove(file) 117 return render_template('index.html') 118 119 120@app.route('/result', methods=['GET', 'POST']) 121def result(): 122 id = request.form.get('id') 123 error = None 124 if not id: 125 error = 'IDを入力してください。' 126 return render_template('index.html', error=error) 127 128 # メイン処理 129 try: 130 get_tweet(id) 131 except Exception: 132 error = 'ユーザーが見つかりませんでした。' 133 return render_template('index.html', error=error) 134 tweets = get_tweet(id) 135 results = separate_tweet(tweets) 136 num = len(results) 137 category_dic = categorize(results, tweets) 138 get_json(category_dic, results, id) 139 result_data = get_result_data(id) 140 return render_template('result.html', id=id, num=num, data=result_data) 141 142 143@app.route('/detail/<category>') 144def detail(category): 145 detail_data = get_detail_data(category) 146 return render_template('detail.html', category=category, data=detail_data) 147 148 149if __name__ == "__main__": 150 app.run() 151

アプリのファイル構成

. ├── __pycache__ ├── config.py ├── .env ├── fastText ├── json_dir ├── main.py ├── mecabrc -> /etc/mecabrc ├── model-1.bin ├── requirements.txt ├── static ├── templates └── usr

試したこと

調べてみて、mecabrcへのパスが通ってないことが原因だと分かったので以下のようなことを試しました。

  • アプリファイルに/usr/local/etcディレクトリを作成しそこに、ローカル上の/usr/local/etc/mecabrcのコピーを追加
  • mecabrcのコピーをアプリファイルに追加し、デプロイ時に以下のビルドコマンドを実行(参考サイト:https://qiita.com/NLPingu/items/6f794635c4ac35889da6
export MECABRC="mecabrc"

結果、どちらもログは変わらずでした。

追記
  • 以下コマンドを実行
apt-get install mecab

結果

Nov 6 12:35:40 PM E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied) Nov 6 12:35:40 PM E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?

補足情報(FW/ツールのバージョンなど)

ビルド環境
ビルドコマンドで、uname -r を実行したところ

5.15.0-1022-aws

と返ってきました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

quickquip

2022/11/06 11:56

export MECABRC="mecabrc" は export MECABRC="/usr/local/etc/mecabrc" の書き損じですか?
a2c6201

2022/11/06 13:35 編集

コメントいただき誠にありがとうございます。 いえ、アプリのルートディレクトリにmecabrcのコピーを追加したため、 export MECABRC="mecabrc" この書き方で問題ないかと考えました。 これだと通らないでしょうか。
quickquip

2022/11/06 15:02 編集

アプリのルートではなくて、カレントディレクトリを指定していることになると思われます(カレントディレクトリに置いたら動くという確信はありません) あと、辞書はどうインストールしているんでしょうか? という疑問もありますが
a2c6201

2022/11/08 13:05

>いえ、アプリのルートディレクトリにmecabrcのコピーを追加したため、 ルートディレクトリではなく、カレントディレクトリの書き損じでした。(すみません) > あと、辞書はどうインストールしているんでしょうか? という疑問もありますが renderの無料プランではシェルが使えないため、インストールが難しいんですよね、、 別のPaaSを使おうと思います、、 コメントいただき本当にありがとうございますmm
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問