カテゴリー: Python

  • UTF-8 BOM付確認

    ベタな処理だなー。って思いながら

    def has_utf8_bom(filepath: str) -> bool:
        """
        UTF-8のファイルがBOM付きかどうかを確認する関数
    
        Parameters:
            filepath (str): 確認対象のファイルパス
    
        Returns:
            bool: True なら BOM付き、False なら BOMなし
    
        Raises:
            なし
        """
        with open(filepath, 'rb') as f:
            first_bytes = f.read(3)
        return first_bytes == b'\xef\xbb\xbf'
    
  • ダウンロードディレクトリを知る

    方法1:pathlib + os + platformdirs(推奨)

    外部ライブラリ platformdirs を使用すれば、クロスプラットフォームでダウンロードフォルダを取得できます。

    インストール:

    pip install platformdirs

    コード:

    from platformdirs import user_download_dir
    from pathlib import Path
    
    downloads_path = Path(user_download_dir())
    print(downloads_path)
    

  • PDF処理

    Python でテキストをPDFにする

    pip install reportlab
    from reportlab.pdfgen import canvas
    from reportlab.pdfbase import pdfmetrics
    from reportlab.pdfbase.cidfonts import UnicodeCIDFont
    
    # PDF生成
    c = canvas.Canvas("output.pdf")
    
    # 日本語フォント登録(MSゴシックやIPAフォント等が不要な、built-inの CIDFont を使います)
    pdfmetrics.registerFont(UnicodeCIDFont('HeiseiKakuGo-W5'))
    c.setFont("HeiseiKakuGo-W5", 14)
    
    # テキスト出力
    lines = [
        "1.あいうえお",
        "2.かきくけこ",
        "3.さしすせそ"
    ]
    
    y = 800  # 開始Y座標
    for line in lines:
        c.drawString(100, y, line)
        y -= 30  # 行間調整
    
    c.save()
    

  • Beautiful Soup

    インストール方法

    pip install beautifulsoup4 lxml
  • ファイルパス確認

    絶対パスか相対パスかどうかを確認する方法

    from pathlib import Path
    
    def check_if_full_path(path):
        p = Path(path)
        if p.is_absolute():
            return "フルパスです"
        else:
            return "ファイル名または相対パスです"
    
    # 使用例
    path = '/home/user/file.txt'
    print(check_if_full_path(path))  # 出力: フルパスです
    
    path = 'file.txt'
    print(check_if_full_path(path))  # 出力: ファイル名または相対パスです
    
  • argparse の利用

    import argparse
    
    def main():
        # 説明
        parser = argparse.ArgumentParser(description="引数のデモ")
        # 必須の場合
        parser.add_argument("name", type=str, help="名前を指定してください")
        # 任意の場合
        parser.add_argument("-a", "--age", type=int, help="年齢を指定できます(オプション)")
        
        args = parser.parse_args()
        
        print(f"名前: {args.name}")
        if args.age:
            print(f"年齢: {args.age}")
    
  • ファイルを開く

    seleniumでファイルを開くのは難しい

    pywinauto を使用して処理を行う

    pip install pywinauto pywin32
    import pywinauto
    
    def fileopen(filepath: str) -> None :
        # pywinautoによる制御
        findWindow = lambda: pywinauto.findwindows.find_windows(title='開く')[0]
    
        dialog = pywinauto.timings.wait_until_passes(5, 1, findWindow)
        pwa_app = pywinauto.Application()
        pwa_app.connect(handle=dialog)
        window = pwa_app['開く']
        window.wait('ready')
    
        #ファイル入力(Alt+N)
        pywinauto.keyboard.send_keys("%N")
        edit = window.Edit4
        edit.set_focus()
        edit.set_text(filepath)
    
        # ダイアログの「開く」ボタンをクリック    
        button = window['開く(&O):']
        button.click()
    

    クリックが反応してくれない場合がある。(フォームが最前面ではないから)ということより、最終的には下記になった

    import pywinauto
    from pywinauto import win32defines
    
    def fileopen(self, filepath: str) -> None :
        # pywinautoによる制御
        findWindow = lambda: pywinauto.findwindows.find_windows(title='開く')[0]
        dialog = pywinauto.timings.wait_until_passes(5, 1, findWindow)
        pwa_app = pywinauto.Application()
        pwa_app.connect(handle=dialog)
        window = pwa_app['開く']
        window.wait('ready')
    
        # ファイル入力(Alt+N)
        pywinauto.keyboard.send_keys("%N")
        edit = window.Edit4
        edit.wait('ready', timeout=3)  # 安定化のため待機
        
        # **前回の入力をクリア**
        edit.type_keys("^a{BACKSPACE}")  # Ctrl + A → Backspace で全削除
        time.sleep(0.2)  # 短い待機(高速化のため0.2秒)
    
        # **新しいパスを入力**
        edit.set_text(filepath)
        time.sleep(0.5)  # 入力が確実に反映されるように待つ
    
        try:
            # 最前面に持ってくるためにウィンドウにメッセージを送る
            window.send_message(win32defines.WM_SYSCOMMAND, win32defines.SC_RESTORE)
            # ダイアログの「開く」ボタンをクリック
            button = window['開く(&O):']
            button.wait('visible', timeout=3)  # ボタンが表示されるまで待つ
            # ボタンにフォーカスを当てる
            button.set_focus()
            # ボタンをクリック
            button.click()
            button.click()
            button.click()
    
            print(f"[INFO] 開くボタンをクリック成功")
    
        except (pywinauto.findbestmatch.MatchError, pywinauto.timings.TimeoutError) as e:
            print(f"[WARN] 開くボタンのクリック失敗(2回目クリック不要だった)")
            time.sleep(0.5)  # 少し待ってから再試行
        except Exception as e:
            print(f"[ERROR] 予期せぬエラー: {e}")
            time.sleep(0.5)
    
    
  • 画像取得

    要インストール: requests

    画像ダウンロード処理のサンプル
    codeとaddressという項目を持つCSVを読み込んで、当該のaddress(カンマ区切りで複数定義されている)の画像をダウンロードして、codeの名称をベースとしたファイル名で保存する。
    ということをしている。

    """
    ファイル名: main.py
    作成者: UniqueVisionProductions
    
    ダウンロード動作テスト用 メインファイル
    
    このファイルには、以下の関数が含まれています:
    - main: 起点となる関数
    
    変更履歴
    - Ver.1.0.0.1 :
    """
    import csv
    import os
    import requests
    
    def main():
        """
        メイン関数
    
        Parameters:
            None
    
        Returns:
            None
    
        Raises:
            None
        """
        # ユーザーのホームディレクトリを取得
        desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
        # 読み込み元ファイル
        base_filename = "images_01.csv"
    
    
        csvfilepath = os.path.join(desktop_path, base_filename)
        # ダウンロード先
        download_dir = os.path.join(desktop_path, "imagedownload")
        # ディレクトリが存在しない場合に作成
        os.makedirs(download_dir, exist_ok=True)
    
        with open(csvfilepath, newline="", encoding="shift_jis") as f:
            reader = csv.DictReader(f)  # ヘッダー行をキーにして辞書として読み込む
            records = [row for row in reader]  # 各行を辞書としてリストに格納
    
    
        for record in records :
            count = 0
            for url in record['address'].split(","):
                filename = f"{record['code']}_{count}.jpg" if count else f"{record['code']}.jpg"
                filepath = os.path.join(download_dir, filename)
    
                response = requests.get(url)  # 画像を取得
    
                if response.status_code == 200:
                    with open(filepath, "wb") as f:
                        f.write(response.content)  # バイナリデータを書き込み
                    # ファイル項番更新
                    count+=1
                    print(f"{record['code']}: ダウンロード完了")
                else:
                    print(f"{record['code']} ダウンロード失敗:", response.status_code)
    
    
    if __name__ == "__main__":
        try:
            # 引数なし
            main()
        except Exception as e:
            # エラー検出
            print("ERROR : ", e)
        finally :
            # キー入力待ち
            input("Press any key to finish.")