💵 CLINEに賭けてみた 2ドル目 🤼 

# 前回の記事
https://qiita.com/u83unlimited/items/0b26fb52fb18f36b595b

# 目標
![スクリーンショット 2025-03-04 040033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307259/4cb136c5-954b-4ccb-8d4d-445d91d51ea1.png)


- 学生時代に作った[<ruby>古<rp>(</rp><rt>いにしえ</rt><rp>)</rp></ruby>のテーブルレイアウトのウェブサイト](https://21st-century-power-bomb.netlify.app/business/age)からデータをスクレイピングする
    - 微妙にドメインの話が後で出てくるので深堀りすると、国内外のプロレスラーの生年月日をまとめた表があり、抽出したい
    - 当時DreamWeaverをエクセル代わりに使って手打ち入力したので、元となるエクセル等のデータファイル等が存在しない
- **TypeScriptの型はこちらで用意する**ので以下のタスクをやってほしい
    - 自動テストの作成とチェック
    - データを巨大TSオブジェクトとして保存
    - データをDBにインサートするSQLファイルの作成
    - TypeScriptの型からPrismaのスキーマ定義の生成

# プロンプト
今回は長くなることが予想されたのでmdとして取っておきました。

## 制約
- 原則このフォルダ（21CPB）以外のファイルを読み書きするな。必要があれば許可を求めること
- 同じ課題で2度以上エラーが起きた場合は絶対にユーザーの判断を求めること。例外はない。
- 渡した型を変更してはならない。もし疑問点があればユーザーに尋ねること
- 解析したデータを変形するのはいいが、存在しないデータを捏造してはいけない。処理できないデータがある場合、ユーザーに尋ねること。例外はない。

## タスク内容

1. プロレスラーの年齢を纏めたウェブページ（./business/age.htm）のHTMLを解析して各レスラーのデータを抽出してほしい
	1. メインとなるカラムには`誕生日`,`名前`,`所属団体(mainPromotion)`が記載されている。
	2. 所属団体はカッコ`（）`がついている。
	3. ただし**名前が二つあるレスラーがおり、別名義もカッコがついている**。この場合、後ろのカッコが団体名となる。
2. TypeScriptの型はこちらで提供するので取得したデータをテストに合うように変形した上で、あてはまるかチェックしてほしい。
3. このチェックはvitestを用いて作成してほしい
4. チェックが全て通ったらdata.tsとして保存してほしい。
5. また同データを元に `prowrestlers`テーブルを用意するので、テーブルが存在する前提で全データをinsertするSQL文を作成してほしい。DBはmySQL/postgreSQLのどちらか。
	1. テーブルのカラムは後述するデータ型を元にしてほしい。
6. `promotion`型を元にマスターテーブルの`promotions`テーブルを用意するので同じように全データをinsertするSQL文を作成してほしい。
7. 前述の2テーブルについてPrismaのスキーマも後述のデータ型から作成してほしい
8. 大昔に作ったサイトのためnpmによるライブラリ管理等は行っておらず、必要なライブラリはインストールすること。

## データ型
```ts
// ざっと見て目コピで起こしたが実は足りてない
// 当時（00年代後半）はインディ花盛りだったので団体マジで多かったなぁ……（遠い目）
type Promotion = "全日本"|"新日本"|"ノア"|"ドラゴンゲート"|"DDT"|"W-1"|"ZERO1"|"大日本"|"みちのく"|"IGF"|"STYLE-E"|"K-DOJO"|"666"|"FREEDOMS"|"ユニオン"|"パンクラスmission"|"ドラディション"|"ダイヤモンド"|
"WWE"|"TNA"|"ROH"|"AAA"|
"フリー"|"半引退"|"引退"|"故人"

type Prowrestler = {
	name: string,
	dateOfBirth: Date,
	mainPromotion: Promotion,
	isJapanese:boolean
	// 現在の年齢や平成等の和暦は生年月日から逆算するので不要
}

```


# 成果物
Githubのコミットです。後述しますが、下準備に時間かけたこと、タスク始めてから型の間違いや情報漏れで手戻りを繰り返したので**所要時間約1時間、約3$なり。**

https://github.com/u83ism/21CPB/commit/1379a598b6648fb5236832cf6d09f76e38f51a6f

ざっくりとしか見てませんが、ほぼ成功していそうです。

# 注目点/気になった点
- 抽出スクリプト組むの流石に早い！
- 相変わらず「渡した型を変更してはならない」つってるのに「データの漏れと思われます。型を修正しましょう」とかプロンプトを無視しようとする
- 最終成果物にいくつか問題がある
    - 実はデータオブジェクトの生年月日の型がミスってlinterがエラーはいている（`dateOfBirth : new Date("1989-07-27T15:00:00.000Z")`みたいな形で出力するか、ファイル出力用に`dateOfBarth:string`の類似の型を作る必要がある）
    - SQLでシングルクォート入りのレスラー名（Men'sテイオー）のエスケープ処理ができていない
    - レスラーの名前に別名義があることは理解しているが、最終成果物からそぎ落としてしまった（指示漏れ）
- こっちの情報伝達不足で不測の事態が起きた時の推測能力は人間にはまだ及ばず、明後日の方向に走り出すので途中で止める必要がありました。ほったらかしはやはり無理
- また今回は自動テストを作成し、抽出したデータをテストしろと指示しましたが、コンソールの出力が取得できない関係で自動テストの成否が認識できず、テストが落ちてるのに後のタスクを進めてしまう問題もありました
- あと最後、データオブジェクトの生成は一瞬だったんですけど、単純なのにSQLの生成がやたら遅く、超タイピング早い人間が打ってるような速度で1分以上かかったのが謎
- 圧巻だったのは、実は**このテーブルの年表示や和暦、年齢等が書かれてる見出し、JSで動的生成しててHTMLファイルは空白になっています。** このこと忘れていて全レスラーの生年を何故か2014年扱いにする（プロンプト無視……😠）のはアレでしたが、指示出したら**作成スクリプト（jQuery）を読み込んで解析し、動作させずに正しい生年を割り出したところです。** 開発サーバー建ててヘッドレスブラウザで見るかなと予想していたので正直たまげましたね

# 総評
- プロンプト見てもわかる通り、結構マメにテーブルの情報与えていてなお伴走と試行錯誤必須だったこと、推測能力も劣るので、完全自動化は相当厳しそう
- ただ2000円ぐらいで駆け出しPython（Beautiful Soup）使いなり、JS（jQuery）使い呼んで同じことやらせたら4時間～8時間（SQLやPrisma,Vitest等、単価的に全部知ってることを期待するのは無理があるので調査コスト込）ぐらいはかかると思うので、**半日～1日/1万～1万5000円はかかる仕事が1時間/自分の時間単価+3$で済んでる**んだから破格としか言いようがない
- クラウドワークスとかでスクレイピングの仕事ありますけど簡単なやつなら入れ食い状態になりそう。ヘッドレスブラウザいる系はどうでしょうね。

# 後書き
- 学生時代（00年代）から趣味で複数サイトやっていてテーブルレイアウトからデータ抽出したいやつ、他にも多数あるんですけど、自分でやるには面倒すぎる、人に頼むには高くなりすぎと棚上げしてたやつの解決の目途が立ったのはめっちゃいいですね。
- 他のやつは複数ページにまたがる大規模なやつとか複雑なテーブルレイアウトとかあるので、この規模で3ドルなら、やりたいやつ全部抽出したらトータル50ドルぐらいかかりそうだなとw まぁ数万レベル確定よりかは遥かにマシなんでケチるなという話なんですけど。

# 続編
https://qiita.com/u83unlimited/items/f6045138dbb4598f5453