1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

subprocess.runが吐いた文字列をJsonにデコードできない?ANSIエスケープシーケンスが原因かも

Last updated at Posted at 2023-12-17

pythonで、ghコマンドを叩いてGithubからデータを取得しようとしたある日のこと。

突然のJSONDecodeError

subprocess.runで次のghコマンドを叩きました。
gh issue list --json title,url

レスポンスの文字列
スクリーンショット 2023-12-17 22.00.33.png

文字列のままでは扱いづらいため、json.loadsによってJsonにデコードすると

---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
Cell In[123], line 18
     16 # subprocessモジュールを使用してzshコマンドを実行
     17 result = subprocess.run(["zsh", "-c", zsh_command], stdout=subprocess.PIPE, text=True).stdout
---> 18 JSON(json.loads(result))
(略)
JSONDecodeError: Expecting value: line 1 column 1 (char 0)

JSONDecodeErrorが発生しました。

レスポンスの文字列をよく見ても、コピーしてJson構文を機械的にチェックしてみても、おかしなところは見当たりません。では、いったいなぜ・・

JSONDecodeErrorの原因

レスポンスの文字列をもう一度見てみましょう。
スクリーンショット 2023-12-17 22.00.33.png

文字が青色や緑色で着色されています(※Jupyter Labという開発環境での表示です)。これがJSONDecodeErrorを引き起こしている原因でした。

ANSIエスケープシーケンスと呼ばれる特殊コードを文字列に含めることによって実現されているようです。

JSONDecodeErrorの解決方法

下記コードによって、ANSIエスケープシーケンスを除去します。

def remove_ansi_escape_codes(text):
    # ANSIエスケープコードを削除
    ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
    return ansi_escape.sub('', text)

これによって、json.loadsでJSONDecodeErrorになる問題を無事回避できました。
スクリーンショット 2023-12-17 22.18.30.png

おわりに

標準出力の着色の仕組みを理解していないと、検討がつかず焦りますね。
コマンドを叩いた結果を処理するときは、ANSIエスケープシーケンスに気をつけましょう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?