俺の考えた最強のPython自動化ツールライブラリ集

# はじめに
こんにちは、GxPの土田です。
この記事は[グロースエクスパートナーズ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/gxp) 2周目の24日目です。トリ前に失礼します。
自動ツール制作大好きマンの私が、これさえあればなんでもできるPythonライブラリたちを紹介しちゃいます！

# Tools

## PC操作

### subprocess

https://docs.python.org/ja/3/library/subprocess.html

```python
import subprocess

subprocess.run(['ping', 'google.com'], shell=True, encoding='shift-jis')

""" output
google.com [2404:6800:4004:823::200e]に ping を送信しています 32 バイトのデータ:
2404:6800:4004:823::200e からの応答: 時間 =5ms
2404:6800:4004:823::200e からの応答: 時間 =6ms
2404:6800:4004:823::200e からの応答: 時間 =7ms
2404:6800:4004:823::200e からの応答: 時間 =5ms

2404:6800:4004:823::200e の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 5ms、最大 = 7ms、平均 = 5ms
CompletedProcess(args=['ping', 'google.com'], returncode=0)
"""
```
コマンドがpythonから実行できるライブラリ。
つまり**コマンドでできることは何でもできる**。
```python
result = subprocess.run(['ping', 'google.com'], shell=True, stdout=subprocess.PIPE, encoding='shift-jis')
print(result)

""" output
CompletedProcess(args=['ping', 'google.com'], returncode=0, stdout='\ngoogle.com [2404:6800:4004:823::200e]に ping を送信しています 32 バイトのデータ:\n2404:6800:4004:823::200e からの応答: 時間 =5ms \n2404:6800:4004:823::200e からの応答: 時間 =6ms \n2404:6800:4004:823::200e からの応答: 時間 =6ms \n2404:6800:4004:823::200e からの応答: 時間 =5ms \n\n2404:6800:4004:823::200e の ping 統計:\n    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、\nラウンド トリップ の概算時間 (ミリ秒):\n    最小 = 5ms、最大 = 6ms、平均 = 5ms\n')
"""
```
`stdout=subprocess.PIPE` を使えばコマンドの標準出力を変数に受け取れる。
`subprocess.Popen()` を使えばコマンドを並列で実行できる（らしい、使ったことはない）。

---

### PyAutoGUI

https://pyautogui.readthedocs.io/en/latest/

```python
import pyautogui

pyautogui.click(200, 100) # 画面左上から 右に200px, 下に100px をクリック
pyautogui.write('test') # 'test' とキーボード入力

r, g, b = pyautogui.pixel(200, 100) # 200, 100 の色を取得
print(f'r:{r}, g:{g}, b:{b}')

""" output
r:12, g:12, b:12
"""
```
マウス/キーボード 操作ができるライブラリ。
つまり**ユーザがPCを操作してできることは何でもできる**。実質最強ライブラリ。
デメリットとして、裏で動いてくれるものではなく、実際に マウス/キーボード 操作を発生させるため、実行中は腕を組んでPCを眺めているか、トイレで時間を潰すことになる。
それでも単調で面倒なだけの作業を勝手にやってくれるのはありがたい。

## ファイル操作

### pytesseract

https://pypi.org/project/pytesseract/

```python
from PIL import Image
import pytesseract

image = Image.open('./image.png')
text = pytesseract.image_to_string(image)
print('result: `', text, '`')

""" output
result: `text from image`
"""
```

OCRエンジンのTesseractを動かせるライブラリ。
PyAutoGUIで操作をして、スクリーンショットを撮り、画面に表示された文字を認識して判定に利用、次の操作を分岐する。などなど夢が広がる。

---

### glob

https://docs.python.org/3/library/glob.html

```python
from glob import glob

python_files = glob('./**/*.py', recursive=True)
for f in python_files:
    print(f)

""" output
.\main.py
.\test.py
.\sub\sub1.py
.\sub\sub2.py
.\sub\foo\bar.py
"""
```
条件に合致するファイルやフォルダを一覧取得できるライブラリ。
`with open()` と組み合わせれば条件に合致したファイルすべてに特定の操作を行うなどができる。

---

### json

https://docs.python.org/3/library/json.html

```python
# 書き込み
with open('./test.json', 'w') as f:
    json.dump({'name': 'valueeee'}, f)

# 読み取り
with open('./test.json', 'r') as f:
    data = json.load(f)

print(data)

""" output
{'name': 'valueeee'}
"""
```
jsonの読み書きが2行で完結するライブラリ。
ツールの設定ファイルをconfig.jsonに書いておけば、これで読み取るだけでおなじみのdictとして扱える。

---

### jsoncomment

https://pypi.org/project/jsoncomment/

```python
from jsoncomment import JsonComment
import json

# 書き込み（コメントは含められない）
with open('./test.jsonc', 'w') as f:
    json.dump({'name': 'valueeee'}, f)

# 読み取り（コメント付きでもOK）
with open('./test.jsonc', 'r', encoding='utf-8') as f:
    parser = JsonComment()
    data = parser.load(f)

print(data)

""" output
{'name': 'valueeee'}
"""
```
.jsonc 対応ライブラリ。
設定ファイルにコメントを書いておけるようになる。
もちろんjsonも読み取れるので実質上位互換。

---

### openpyxl

https://openpyxl.readthedocs.io/en/stable/

```python
import openpyxl

# 新規作成
workbook = openpyxl.Workbook()
workbook.active['A1'] = 'hello'
workbook.save('test.xlsx')
workbook.close()

# 読み取り
workbook = openpyxl.load_workbook('test.xlsx')
print(workbook.active['A1'].value)

""" output
hello
"""
```
Excelファイルを操作できるライブラリ。
`python-pptx`, `python-docx` などなど、別形式のOffice系ファイルを操作するライブラリもあり。

---

### xlwings

https://docs.xlwings.org/en/latest/

```python
import xlwings as xw

# 新規作成と書き込み
app = xw.App(visible=False)  # ヘッドレスモードで起動
book = app.books.add()
sheet = book.sheets[0]
sheet.range('A1').value = 'hello'
book.save('test.xlsx')
book.close()
app.quit()

# 読み取り
app = xw.App(visible=False)
book = app.books.open('test.xlsx')
value = book.sheets[0].range('A1').value
print(value)
book.close()
app.quit()

""" output
hello
"""
```

ExcelファイルをVBAライクに操作できるライブラリ。
上記openpyxlでは、古いバージョンのExcelファイルとして保存されてしまう問題点があるが、こちらはPCにインストール済みのExcelアプリケーションに依存するため、ユーザが操作した時と全く同じものができあがる。
デメリットとして、Excelアプリケーションを動かすため、インストール済みである必要があること、アプリを動かす都合上少し重いことがあるが、VBAに慣れている人にはものすごく書きやすいライブラリとなっている。
一部VBAから完全置換はできず、com APIを直接呼び出してやる必要があるが、openpyxlよりはできることが多い。
ちなみに、Excel-Pythonの双方向実行が可能で、Pythonで定義した関数をExcel関数から呼び出すこともできるらしい。

---

### Pillow(PIL), opencv-python

https://pillow.readthedocs.io/en/stable/

https://pypi.org/project/opencv-python/

```python
from PIL import Image

image = Image.open("input.jpg")

width, height = image.size
new_width = width // 2
new_height = height // 2
resized_image = image.resize((new_width, new_height))

resized_image.save("output.jpg")

resized_image.show()
```
```python
import cv2

image = cv2.imread("input.jpg")

height, width, channels = image.shape
new_width = width // 2
new_height = height // 2
resized_image = cv2.resize(image, (new_width, new_height))

cv2.imwrite("output.jpg", resized_image)

cv2.imshow("Resized Image", resized_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
どちらも画像操作系ライブラリ。
ちょっとした画像編集ならPillow、
画像分析をがっつりしたいならopencv-python、
といった使い分けをする。

## 実行

### pyinstaller

https://pyinstaller.org/en/stable/index.html

```shell
pyinstaller ./main.py --onefile
```
https://qiita.com/tshimada-gxp/items/9d37263e021ac393a693

去年の [GxP Advent Calendar 2022](https://qiita.com/advent-calendar/2022/gxp) でも紹介されていました。

ツールを作って配布するにあたって、配布対象に「pythonをインストールしてこのファイルを実行してください」ではなく「このexeを実行してください」ができる。
何より自作ツールが実行ファイルになっているのはかっこいい。

## ブラウザ操作

### playwright

https://playwright.dev/python/docs/intro

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586144/c5222c76-3bec-1314-7fe5-d01c652ae33b.png)
seleniumやpuppeteerと同じ、ブラウザ自動テストツール。
特定のページにログインして、データを取得するなど、スクレイピングツールとして非常に優秀。

```shell
playwright codegen google.com
```
を実行すると、Chromiumが立ち上がり、クリックや入力操作をするとそれを検知し、勝手にプログラムに起こしてくれる。
このcodegenが標準で搭載されているのがかなりつよつよ。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586144/06d1d9ae-fe94-8075-b75f-36f615285d3a.png" 
 width="500"/>
pythonの他にも言語・記法が複数ある。
おすすめはasync/awaitをいちいち書かなくてよいPython Library。

## GUI

### tkinter

https://docs.python.org/3/library/tkinter.html

```python
import tkinter as tk

def show_input():
    result_label.config(text=entry.get())

window = tk.Tk()
window.title("title")

entry = tk.Entry(window, width=30)
entry.pack(pady=10)

button = tk.Button(window, text="確定", command=show_input)
button.pack()

result_label = tk.Label(window, text="")
result_label.pack(pady=10)

window.mainloop()
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586144/db5cf25b-a388-6e8e-d598-c9955add999b.png" />

GUI構築のためのpython標準ライブラリ。
「入力欄とボタンだけ欲しい」とかなら数行。
特に見た目に拘らずに挙動だけのGUIが欲しいだけであれば爆速でGUIを実装できる。
最初から最後までpythonだけで完結できるのが利点。

---

## pywebview
https://pywebview.flowrl.com/
```python
import webview
webview.create_window('Hello world', 'https://pywebview.flowrl.com/')
webview.start()
```

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586144/9a723e52-3042-a818-01e2-d8ec7cfa8e3c.png" />

GUIを Python + HTML/CSS/JavaScript で作れるライブラリ。

ローカルの.htmlファイルを読み取らせて表示することもできるし、pythonで動的に生成したhtml形式の文字列を表示させることもできる。
ちょっと頑張れば python <-> JavaScript でデータを送受信することも可能。
両者動的型付け言語で、変数名等のリファクタリングも効かないのが難点。
CDNを読み込めばVue.js等も使えるので便利。
あくまで小規模なGUIを作るのにhtmlの方がやりやすいときに使うもので、中大規模のGUIにはおとなしくelectronを使いましょう。

# おわりに
これがあれば皆さんの面倒な作業を自動化できますね？
勤怠登録を毎日自動化して、休みの日も登録されてしまわないように注意してくださいね！