Python ライブラリのライセンス情報,説明,URLを取得してcsvへ保存する「pip-licenses」

 本記事では、インストール済のライブラリ(パッケージ)のライセンス情報、説明、URLを取得して、csvファイルへ出力するPythonスクリプトを載せました。

■ライブラリ「pip-licenses」を次のようにpipでインストールします

pip install pip-licenses

 本スクリプトを実行すると、下図のように左から順に、Pythonライブラリ名,バージョン,ライセンス名,パッケージの説明,URLをcsvへ出力します。

■本スクリプト

import os
import subprocess
import io
import pandas as pd

import datetime
now = datetime.datetime.now()
now = now.strftime("%y%m%d")#_%H%M%S") # 現在の日時を取得
print(now)


# In[2]:


# 実行コマンドをリストで設定
cmd_list = ['pip-licenses', '-d', '-u']

# 環境設定
my_env = os.environ.copy()
my_env["PYTHONIOENCODING"] = 'utf-8'

# コマンドを実行する
result = subprocess.run(
    cmd_list, # 実行コマンド
    encoding = 'utf-8', #文字列として取得する場合(指定しないとバイト列)
    stdout = subprocess.PIPE, # 標準出力
    stderr = subprocess.PIPE, # 標準エラー出力
    #shell = True, # 文字列で指定する場合True
    #text = True,
    env = my_env,
)
#print('stderr', result.stderr)
#print('stdout\n', result.stdout)


# In[3]:


# ファイルオブジェクトで扱う
f = io.StringIO(result.stdout)
row_list = []
for i, s in enumerate(f):   
    # 空白を削除してリストに格納
    buf_list = s.split()
    
    if i == 0: # 0行目は列名
        new_buf_list = buf_list.copy()
    else:
        # 上記リストの3列目以降を抽出して文字列にする
        buf_str = ' '.join(buf_list[2:])
        #print(buf_str)
        
        # url以降の文字列の位置を取得して、ライセンス名を取得する
        if 'http' in buf_str:
            cnt_http = buf_str.find('http')
        else:
            cnt_http = buf_str.find('UNKNOWN')
        my_license = buf_str[:(cnt_http - 1)]
        #print(my_license)
        
        # url以降の文字列を取得する
        buf_url = buf_str[cnt_http:]
        #print(buf_url)
        
        # urlの終わりをスペースで判断して、urlを取得する
        cnt_space = buf_url.find(' ')
        my_url = buf_url[:cnt_space]
        #print(my_url)
        
        # urlの終わりを判断したスペースの次以降を説明文として取得する
        my_description = buf_url[(cnt_space + 1):]
        #print(my_description)

        # 新しい行リストを作成する
        new_buf_list = buf_list[:2] + [my_license, my_url, my_description]
        #print(new_buf_list)
        
    # リストへ格納
    row_list.append(new_buf_list)
    
#row_list


# In[4]:


# パンダスデータフレームへ変換
df = pd.DataFrame(
    row_list[1:], # 2行目からデータ
    columns = row_list[0], # 1行目を列名 
)
df


# In[5]:


# 列順を変更する(列番号)
df2 = df.copy()
df2 = df2.iloc[:, [0, 1, 2, 4, 3]]
df2


# In[6]:


# ライセンスの列に、unknownの文字列がある行を抽出する
df2_unk = df2.query('License.str.contains("UNKNOWN")', engine = 'python')
df2_unk


# In[7]:


# ライセンス不明をすべて UNKNOWN へ置換する
df2_unk['License'] = 'UNKNOWN'
df2_unk


# In[8]:


# インデックス番号をリストで取得
target_index = df2_unk.index.to_list()
target_index


# In[9]:


# 指定インデックスの行を削除する
df3 = df2.drop(target_index)
df3


# In[10]:


# データフレームを結合
df4 = pd.concat([df3, df2_unk])
df4


# In[11]:


# インデックスをソートする
df_s = df4.sort_index()
# csvファイルへ出力
df_s.to_csv(now + '_python_package_license.csv', index = False)
df_s


# In[12]:


# 取得したライセンス名一覧を表示
license_list = df_s.groupby('License').count().index.to_list()
print(license_list)

以上

<広告>