0
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?

Pythonで作る業務自動化ツール10選|ITコンサルが実務で使うスクリプト集【動くコード付き】

0
Posted at

はじめに

「Pythonで業務を自動化したい」

この記事では、ITコンサルタントとして実務で使っている業務自動化スクリプト10選を、動くコード付きで紹介します。

Python初〜中級者がそのまま使えるものを厳選しました。


自動化ツール一覧

# ツール 削減できる作業
1 Excelレポート自動生成 毎週のレポート作成
2 メール一括送信 定型メールの送付
3 PDFからテキスト抽出 契約書・資料の読み込み
4 Webスクレイピング 情報収集・価格監視
5 ファイル整理・リネーム フォルダ管理
6 Slack通知ボット チームへの定時報告
7 Google Sheets自動更新 数値の転記作業
8 画像の一括リサイズ 資料・SNS用画像処理
9 CSVデータ集計・可視化 売上・KPI分析
10 AI要約ボット(Claude連携) 議事録・長文の要約

① Excelレポート自動生成

import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.chart import BarChart, Reference
from datetime import datetime

def create_weekly_report(data: list[dict], output_path: str):
    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = "週次レポート"

    # ヘッダー設定
    headers = ["日付", "売上", "件数", "平均単価"]
    for col, header in enumerate(headers, 1):
        cell = ws.cell(row=1, column=col, value=header)
        cell.font = Font(bold=True, color="FFFFFF")
        cell.fill = PatternFill(fgColor="1F4E79", fill_type="solid")
        cell.alignment = Alignment(horizontal="center")

    # データ入力
    for row, d in enumerate(data, 2):
        ws.cell(row=row, column=1, value=d["date"])
        ws.cell(row=row, column=2, value=d["sales"])
        ws.cell(row=row, column=3, value=d["count"])
        ws.cell(row=row, column=4, value=d["sales"] // d["count"] if d["count"] else 0)

    # 棒グラフ作成
    chart = BarChart()
    chart.title = "週次売上推移"
    data_ref = Reference(ws, min_col=2, min_row=1, max_row=len(data)+1)
    chart.add_data(data_ref, titles_from_data=True)
    ws.add_chart(chart, "F2")

    wb.save(output_path)
    print(f"レポート出力: {output_path}")

# 使用例
sample_data = [
    {"date": "2026-08-25", "sales": 1200000, "count": 15},
    {"date": "2026-08-26", "sales": 980000,  "count": 12},
    {"date": "2026-08-27", "sales": 1450000, "count": 18},
]
create_weekly_report(sample_data, "weekly_report.xlsx")

② メール一括送信(宛先リストから自動送信)

import smtplib, csv
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def send_bulk_email(csv_path: str, subject: str, body_template: str,
                    smtp_user: str, smtp_pass: str):
    with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
        server.login(smtp_user, smtp_pass)

        with open(csv_path, encoding="utf-8") as f:
            for row in csv.DictReader(f):
                body = body_template.format(**row)
                msg = MIMEMultipart()
                msg["From"]    = smtp_user
                msg["To"]      = row["email"]
                msg["Subject"] = subject
                msg.attach(MIMEText(body, "plain", "utf-8"))
                server.send_message(msg)
                print(f"送信完了: {row['email']}")

# CSVフォーマット: name,email,company
# 本文テンプレートに {name} {company} を埋め込める
body = "{name} 様

{company}へのご案内です..."
send_bulk_email("contacts.csv", "【重要】ご案内", body, "you@gmail.com", "password")

③ PDFからテキスト抽出

import pdfplumber, re

def extract_pdf_text(pdf_path: str, pages: list[int] = None) -> str:
    text_parts = []
    with pdfplumber.open(pdf_path) as pdf:
        target = [pdf.pages[i] for i in pages] if pages else pdf.pages
        for page in target:
            text = page.extract_text()
            if text:
                text_parts.append(text)
    return "\n".join(text_parts)

def extract_tables_from_pdf(pdf_path: str) -> list:
    all_tables = []
    with pdfplumber.open(pdf_path) as pdf:
        for page in pdf.pages:
            tables = page.extract_tables()
            all_tables.extend(tables)
    return all_tables

# 使用例
text = extract_pdf_text("contract.pdf")
tables = extract_tables_from_pdf("financial_report.pdf")

④ Webスクレイピング(価格監視)

import requests
from bs4 import BeautifulSoup
import json
from datetime import datetime

def scrape_price(url: str, css_selector: str) -> dict:
    headers = {"User-Agent": "Mozilla/5.0"}
    resp = requests.get(url, headers=headers, timeout=10)
    soup = BeautifulSoup(resp.text, "html.parser")
    element = soup.select_one(css_selector)
    price_text = element.get_text(strip=True) if element else "取得失敗"
    return {
        "url": url,
        "price": price_text,
        "checked_at": datetime.now().isoformat()
    }

def monitor_prices(targets: list[dict], history_file: str = "price_history.json"):
    history = []
    try:
        with open(history_file) as f:
            history = json.load(f)
    except FileNotFoundError:
        pass

    for target in targets:
        result = scrape_price(target["url"], target["selector"])
        result["name"] = target["name"]
        history.append(result)
        print(f"{result['name']}: {result['price']}")

    with open(history_file, "w") as f:
        json.dump(history, f, ensure_ascii=False, indent=2)

⑤ ファイル自動整理

import os, shutil
from pathlib import Path
from datetime import datetime

RULES = {
    ".pdf":  "Documents/PDF",
    ".xlsx": "Documents/Excel",
    ".docx": "Documents/Word",
    ".png":  "Images",
    ".jpg":  "Images",
    ".mp4":  "Videos",
    ".zip":  "Archives",
}

def organize_folder(target_dir: str):
    target = Path(target_dir)
    moved = 0
    for file in target.iterdir():
        if file.is_dir():
            continue
        dest_sub = RULES.get(file.suffix.lower(), "Others")
        dest = target / dest_sub
        dest.mkdir(parents=True, exist_ok=True)
        shutil.move(str(file), str(dest / file.name))
        moved += 1

    print(f"{moved}件のファイルを整理しました")

organize_folder(r"C:/Users/user/Downloads")

⑥ Slack通知ボット

import requests
from datetime import datetime

def post_slack(webhook_url: str, message: str, channel: str = None):
    payload = {"text": message}
    if channel:
        payload["channel"] = channel
    resp = requests.post(webhook_url, json=payload)
    return resp.status_code == 200

def daily_report_to_slack(webhook_url: str, metrics: dict):
    now = datetime.now().strftime("%Y/%m/%d %H:%M")
    lines = [f"*日次レポート {now}*"]
    for key, val in metrics.items():
        lines.append(f"  {key}: {val}")
    post_slack(webhook_url, "\n".join(lines))

# 使用例(Incoming Webhookを事前に設定)
WEBHOOK = "https://hooks.slack.com/services/xxx/yyy/zzz"
daily_report_to_slack(WEBHOOK, {
    "売上": "¥1,234,567",
    "新規ユーザー": "42名",
    "エラー件数": "3件",
})

⑦ Google Sheets自動更新

import gspread
from google.oauth2.service_account import Credentials

def update_google_sheet(sheet_id: str, worksheet_name: str,
                         data: list[list], creds_path: str):
    creds = Credentials.from_service_account_file(
        creds_path,
        scopes=["https://www.googleapis.com/auth/spreadsheets"]
    )
    gc = gspread.authorize(creds)
    ws = gc.open_by_key(sheet_id).worksheet(worksheet_name)
    ws.clear()
    ws.update(data)
    print(f"{len(data)}行を更新しました")

# 使用例
update_google_sheet(
    sheet_id="スプレッドシートのID",
    worksheet_name="Sheet1",
    data=[["日付", "売上"], ["2026-08-30", 1200000]],
    creds_path="service_account.json"
)

⑧ 画像一括リサイズ

from PIL import Image
from pathlib import Path

def batch_resize(input_dir: str, output_dir: str,
                 max_size: tuple = (1200, 630), quality: int = 85):
    src = Path(input_dir)
    dst = Path(output_dir)
    dst.mkdir(parents=True, exist_ok=True)

    for img_path in src.glob("*.{jpg,jpeg,png,webp}"):
        with Image.open(img_path) as img:
            img.thumbnail(max_size, Image.LANCZOS)
            out = dst / img_path.name
            img.save(out, optimize=True, quality=quality)
            print(f"リサイズ完了: {img_path.name} -> {img.size}")

batch_resize("./original", "./resized", max_size=(1200, 630))

⑨ CSVデータ集計・可視化

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams["font.family"] = "MS Gothic"

def analyze_sales_csv(csv_path: str, output_dir: str = "."):
    df = pd.read_csv(csv_path, parse_dates=["date"])

    # 月次集計
    monthly = df.groupby(df["date"].dt.to_period("M")).agg(
        sales_sum=("sales", "sum"),
        count=("sales", "count")
    ).reset_index()

    # グラフ出力
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

    ax1.bar(monthly["date"].astype(str), monthly["sales_sum"] / 1e6)
    ax1.set_title("月次売上(百万円)")
    ax1.tick_params(axis="x", rotation=45)

    ax2.plot(monthly["date"].astype(str), monthly["count"], marker="o")
    ax2.set_title("月次件数")
    ax2.tick_params(axis="x", rotation=45)

    plt.tight_layout()
    plt.savefig(f"{output_dir}/sales_chart.png", dpi=150)
    print(monthly.to_string())

⑩ Claude連携AI要約ボット

import anthropic

client = anthropic.Anthropic()

def summarize_with_claude(text: str, style: str = "議事録") -> str:
    prompts = {
        "議事録": "以下のテキストから議事録を作成してください。決定事項・アクションアイテム・次回予定を明記してください。",
        "要約": "以下のテキストを200文字以内で要約してください。重要なポイントを箇条書きで示してください。",
        "英訳": "以下の日本語テキストを自然な英語に翻訳してください。",
    }
    system = prompts.get(style, prompts["要約"])

    msg = client.messages.create(
        model="claude-sonnet-5",
        max_tokens=2048,
        messages=[{"role": "user", "content": f"{system}\n\n{text}"}]
    )
    return msg.content[0].text

# 使用例
long_text = "会議の書き起こしテキスト..."
summary = summarize_with_claude(long_text, style="議事録")
print(summary)

まとめ:自動化の優先順位

高頻度 × 単純作業 から始めるのが鉄則

優先度高:
  ✅ 毎日やっているコピペ・転記作業
  ✅ 定型フォーマットのファイル生成
  ✅ 定時に行う報告・通知

優先度中:
  ✅ 週次・月次のレポート作成
  ✅ データの収集・整形

後回し:
  ⬜ 例外処理が多い複雑な業務
  ⬜ 人の判断が必要な意思決定

IT資格・PD試験の情報発信と並行して、実務で役立つPython記事も定期投稿しています。

0
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
0
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?