はじめに
こんにちは。エンジニアをしている長井洸太です。
前回までの記事で、GitHub APIとQiita APIを使ってエンジニアを自動検索し、レート制限を回避しながら大量取得する方法をご紹介しました。
ただ、検索結果をターミナルに表示するだけでは実務では使えません。
- 誰にアプローチ済みか記録したい
- Excelでフィルタ・ソートして優先順位をつけたい
- 別のツール(スプレッドシート・SFA)に取り込みたい
こういった要望に応えるには、検索結果をExcelでそのまま開けるCSVとして保存する必要があります。
この記事では、github_engineer_finder.py / qiita_engineer_finder.py に実装したCSV出力機能を解説します。
作ったもの(概要)
GitHub・Qiitaそれぞれの検索スクリプトに save_csv() 関数を実装し、検索結果を1コマンドで以下の形式に自動保存できるようにしました。
- 文字化けしないExcel対応CSV
- リスト型データ(使用言語・タグなど)を1セルに収める整形処理
- 後から項目が増減しても壊れない柔軟な書き込み
py -3 -X utf8 scripts/sales/github_engineer_finder.py --language "Python" --japan --output csv
これだけで Earning/sales/github/2026-07-06_japan.csv のようなファイルが生成されます。
必要なもの
- Python 3.10以上
-
csv(標準ライブラリ、追加インストール不要) -
pathlib(標準ライブラリ)
pip install requests python-dotenv
CSV出力自体は標準ライブラリだけで完結します。
コード(動くサンプル付き)
ポイント1:encoding="utf-8-sig" でExcelの文字化けを防ぐ
Pythonの csv モジュールは通常 utf-8 で書き出しますが、これをそのままExcel(Windows版)で開くと日本語が文字化けします。
先頭にBOM(Byte Order Mark)を付与する utf-8-sig を指定するだけで解決します。
import csv
from pathlib import Path
def save_csv(candidates: list, filepath: Path):
fieldnames = [
"login", "name", "location", "bio",
"public_repos", "followers", "top_languages",
"github_url", "blog", "dm_text",
]
with open(filepath, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore")
writer.writeheader()
for c in candidates:
c["top_languages"] = " / ".join(c.get("top_languages", []))
writer.writerow(c)
print(f"CSV保存: {filepath}")
ポイント2:リスト型データは書き込む前に文字列へ変換する
GitHub APIから取得した「よく使う言語トップ3」は ["Python", "TypeScript", "Go"] のようなリストです。
csv.DictWriter はリストをそのまま1セルに書き込めない(, 区切りで壊れる)ため、join して1つの文字列にしてから渡します。
c["top_languages"] = " / ".join(c.get("top_languages", []))
こうすることでExcel上は Python / TypeScript / Go のように1セルにきれいに収まります。
ポイント3:extrasaction="ignore" で余分なキーがあっても落ちない
--generate-dm を付けた場合だけ dm_text キーが増える、といったように候補者データの持つキーは実行オプションによって変わります。
extrasaction="ignore" を指定しておくと、fieldnames に定義していないキーが辞書に混ざっていてもエラーにならず無視されます。指定しないと ValueError: dict contains fields not in fieldnames で落ちます。
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore")
Qiita版も基本構造は同じ
qiita_engineer_finder.py 側は対象データが変わるだけで、実装パターンは共通です。
def save_csv(candidates: list, filepath: Path):
fieldnames = [
"id", "name", "organization", "location", "description",
"items_count", "followers_count", "top_tags",
"qiita_url", "twitter", "github", "website", "dm_text",
]
with open(filepath, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore")
writer.writeheader()
for c in candidates:
c["top_tags"] = " / ".join(c.get("top_tags", []))
writer.writerow(c)
print(f"CSV保存: {filepath}")
GitHub・Qiitaのどちらも「①エンコードをutf-8-sigに」「②リストはjoinしてから」「③extrasactionで柔軟性を持たせる」の3点だけ押さえておけば、他のAPI連携でも同じ書き方が使い回せます。
使い方(コマンド例)
# GitHubエンジニアを全国検索してCSVのみ出力
py -3 -X utf8 scripts/sales/github_engineer_finder.py --language "Python" --japan --output csv
# Qiitaエンジニアをタグ検索してCSVのみ出力
py -3 -X utf8 scripts/sales/qiita_engineer_finder.py --tag "Python" --output csv
# CSVとMarkdownの両方が欲しい場合(デフォルト)
py -3 -X utf8 scripts/sales/github_engineer_finder.py --language "TypeScript" --kanto --output both
--output オプションで csv / md / both を切り替えられるようにしてあります。Excelで管理したいときは csv、記事や資料に貼りたいときは md を選ぶ運用です。
出力サンプル(実際の結果)
生成されるCSVをExcelで開くとこのようなイメージになります。
| login | name | location | public_repos | followers | top_languages | github_url |
|---|---|---|---|---|---|---|
| exampleuser1 | Taro Yamada | Tokyo | 42 | 128 | Python / Go / TypeScript | https://github.com/exampleuser1 |
| exampleuser2 | Hanako Sato | Osaka | 15 | 34 | Python / Rust | https://github.com/exampleuser2 |
フィルタ機能を使えば「フォロワー100人以上」「Python使用者のみ」のように、Excel上でそのまま絞り込みができます。
やってみてわかったこと
「Excelでそのまま開ける」が現場では一番大事
どれだけ検索精度を上げても、出力結果がExcelで文字化けした瞬間に使ってもらえなくなります。utf-8-sig の1行を入れるかどうかで、ツールが実際に使われるかが決まると感じました。
リスト型データはCSVと相性が悪い
APIのレスポンスは配列で返ってくることが多いですが、CSVは基本的に「1セル1値」の世界です。書き込む直前に文字列へ変換する一手間を挟むだけで、扱いやすさが大きく変わります。
項目を増やしても壊れない設計にしておくと後が楽
--generate-dm の有無でキーの数が変わるような場面は今後も出てきます。extrasaction="ignore" を最初から入れておいたおかげで、機能追加のたびにCSV出力側を直す必要がなくなりました。
おわりに
CSV出力ができたことで、検索したエンジニア候補を「見るだけ」から「管理する」段階に進められるようになりました。
次回は、GitHub・Qiita・connpassで集めたエンジニア情報を統合してひとつのリストにする方法をご紹介する予定です。
毎日X(Twitter)・Instagram・LinkedInで自動化ツールや開発の話を投稿しています。ぜひ繋がりましょう!