29
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ClaudeでSEOチェッカーとQiita自動いいねツールを作ってみた

29
Last updated at Posted at 2026-04-15

はじめに

最近、Claudeについて学ぶ機会があり、
前回は、「作ったものをどう届けるか」という視点の重要性について整理しました。

今回はそこから一歩進めて、「実際に作るとどうなるのか?」を検証してみました。

従来の開発とは進め方が大きく異なり、実際に手を動かすことで見えてきた気づきがいくつかありました。本記事ではそれらを整理していきます。

今回作ったもの

# ツール 使ったClaude製品
1 SEOチェッカー(45分で作成) Claude(Cowork / デスクトップ)
2 Qiita自動いいね機能(30分で作成) Claude in Chrome

通常であれば数時間〜数日かかるような内容でも、今回はいずれも1時間以内で作成できました。 Claudeを使うことで、実装までのスピードが大きく変わることを実感しました。

①:SEOチェッカー

仕様

URLとキーワードを入力すると、GoogleでそのURLが何位に表示されているかを確認できるツール。

入力 内容
調査対象URL チェックしたいサイトのURL
キーワード 検索順位を調べたいワード
出力 内容
検索順位 対象URLが何位か
表示タイトル Googleに出ているタイトルと文字数(60文字超で警告)
表示ディスクリプション スニペット文章と文字数(160文字超で警告)
上位10件の競合 1〜10位のURLとタイトル一覧

成果物は seo-checker.html(単一ファイル)+ server.py(プロキシサーバー)の2ファイル構成。

なぜこの技術・ツールを選んだか

▫️Claude製品の使い分けについて

今回2つのClaude製品を使い分けた。最初は「どちらでもできるのでは?」と思っていましたが、実際に触ってみると用途の違いがはっきりしました。
**Claude Cowork(デスクトップ)**はファイルの読み書きやコード実行ができる。HTMLファイルを生成してローカルで動かすような「成果物を作る」タスクに向いている。
Claude in Chromeはブラウザを直接操作できる。ページのボタンを押したり、ログイン済みのサービスを操作したりする「ブラウザ上の作業を自動化する」タスクに向いている。
Qiitaのいいね操作はログイン状態が必要なブラウザ操作なので、Claude in Chromeを選んだのは自然な判断だったと思う。一方でSEOチェッカーはHTMLファイルとして手元で動かしたかったので、Coworkが適していると思いました。

▫️単一HTMLファイル構成について

SEOチェッカーをサーバーレスの単一HTMLファイルで作ったのは、デプロイ不要で即座に動かせるからです。Vercelなどにデプロイすることもできるが、今回の目的(動いているものを見せる)には手元で開けるHTMLで十分でした。
ただ、この構成はAPIキーをHTMLファイルに直接書く形になりやすく、Gitへのコミットや第三者への共有には注意が必要です。今回は検証用途と割り切り、APIキーはHTMLに直書きする形で使用しました。実運用では、APIキーをコードにハードコードせず、サーバー側で環境変数(.envファイルなど)として管理する構成が基本となるそうです。

▫️Pythonプロキシサーバーについて

本来はやりたくなかったです。SerpApiはブラウザからの直接アクセスではCORS制約の問題があると知り、サーバーを挟む構成にしました。
これはClaudeが生成したコードの問題ではなく、外部APIの利用において一般的に考慮すべき制約であり、手書きで実装しても同様に対応が必要になる部分と思われます。
実際、エラー発生時にはClaudeがこの制約を説明した上で解決策まで提示してくれたため、仕組みを理解しながら前に進めた点は素直に助かりました。

プロンプトのラリー概要

大まかに、以下のようなやりとりで作成して行きました。

※実際には、AIの出力に対してわからない部分はググったり、何度かClaudeと壁打ちして進めて行きました。以下に記載しているよりも多くラリーはありました。

① タスク分解を依頼
まずClaudeにタスクを分解してもらうところから始めました。

プロンプト

条件に則り(割愛)
SEOチェッカーを作ります。まずタスクを分解したいです。
どんなタスクが必要でしょうか。

結果

フェーズ1:仕様設計(何をチェックするかを固める)
フェーズ2:技術構成の決定(APIの選定・ページ取得方法)
フェーズ3:実装(UI → API連携 → 表示ロジック → デザイン)
フェーズ4:テスト・調整

② 仕様を最低限に絞る
仕様をどこまで作るか問われたので、以下のように依頼

プロンプト

一旦最低限でお願いします。

→ 入力2項目・出力4項目のシンプルな仕様に合意

③ 手順書の作成を依頼

プロンプト

再現性高く行うために、他の人が作る際も同じものを作れるよう、
適切な指示をマークダウン形式に起こしてほしいです。

結果
何度かAIと会話し、以下のような手順書が完成しました。

## 概要

SERP APIを使い、指定したURLが特定キーワードでGoogleの検索結果に何位表示されているかを確認できるツールを、単一のHTMLファイルとして開発する。

- **対象ブラウザ**:Google Chrome
- **成果物**`seo-checker.html`(単一ファイル)
- **使用ツール**:Claude(Web / デスクトップ)のみ
- **API**:serp api key
・
・

📘 開発手順書全文を見る(再現手順・プロンプト付き)
## 最終的な仕様(最低限)

| 入力項目 | 内容 |
|---|---|
| 調査対象URL | チェックしたいサイトのURL(例:https://example.com) |
| キーワード | 検索順位を調べたいキーワード(例:SEOツール 無料) |

| 出力項目 | 内容 |
|---|---|
| 検索順位 | 対象URLが何位に表示されているか |
| 表示タイトル | Googleの検索結果に出ているタイトルと文字数 |
| 表示ディスクリプション | 検索結果のスニペット文章と文字数 |
| 上位10件の競合 | 1〜10位のURLとタイトル一覧 |

---

## 事前準備

1. SERP APIキーを手元に用意する(Claudeには渡さない)
2. SERP APIのエンドポイントとパラメータを把握する
   - 代表的なもの:`https://api.valueserp.com/search?api_key=YOUR_KEY&q=キーワード&location=Japan&gl=jp&hl=ja`
3. Claudeのデスクトップ版またはWeb版を開く

---

## タスク分解


タスク1:HTMLのUI部分を作る
タスク2:SERP APIの呼び出しロジックを実装する
タスク3:検索結果から対象URLの順位・タイトル・ディスクリプションを抽出する
タスク4:上位10件の競合一覧を表示する
タスク5:APIキーをプレースホルダーに置き換えて動作確認する



## Claudeへの指示(プロンプト)

### ステップ1:UIの骨格を作る


以下の仕様でSEOチェッカーのHTMLファイルを1ファイルで作成してください。
HTML・CSS・JavaScriptはすべて1ファイルにまとめてください。

【機能】
- 「調査対象URL」を入力するテキストフィールド
- 「キーワード」を入力するテキストフィールド
- 「チェック開始」ボタン
- 結果表示エリア(最初は非表示)

【デザイン】
- シンプルで見やすいレイアウト
- 日本語表示
- ローディング中の表示あり

まだAPIの呼び出しは実装しなくてよいです。
UIとレイアウトだけ完成させてください。


---

### ステップ2:SERP API呼び出しを実装する

先ほど作ったHTMLに、以下のSERP API呼び出しロジックを追加してください。

【API仕様】
- エンドポイント:https://api.valueserp.com/search
- パラメータ:
  - api_key: YOUR_API_KEY_HERE(プレースホルダーのままにする)
  - q: ユーザーが入力したキーワード
  - location: Japan
  - gl: jp
  - hl: ja
  - num: 10
- レスポンス形式:JSON

【実装内容】
- チェックボタン押下でAPIをfetchで呼び出す
- ローディング表示を出す
- レスポンスのJSONをconsole.logで出力する(確認用)
- エラー時はアラートまたはエラーメッセージを表示する

APIキーの部分は「YOUR_API_KEY_HERE」という文字列をプレースホルダーとして残してください。

---

### ステップ3:検索順位・タイトル・ディスクリプションを表示する


SERP APIのレスポンスJSONには「organic_results」という配列が含まれています。
各要素には以下のフィールドがあります:
- position: 検索順位(数値)
- link: URL
- title: タイトル
- snippet: ディスクリプション

このデータを使って、以下を画面に表示してください。

【表示内容1:対象URLの結果】
- ユーザーが入力したURLが organic_results に含まれているか判定する
- 含まれていれば:順位・タイトル(文字数付き)・ディスクリプション(文字数付き)を表示
- 含まれていなければ:「上位10件に表示されていません」と表示

【表示内容2:上位10件の競合一覧】
- organic_results の全件をテーブルで表示
- 表示項目:順位・タイトル・URL

文字数は「タイトル(32文字)」のように括弧書きで表示してください。


---

### ステップ4:見た目を整える

SEOチェッカーの結果表示を以下のように改善してください。

- 対象URLが見つかった場合は緑色の背景でハイライト表示
- 見つからなかった場合は赤色の背景でハイライト表示
- タイトルが60文字超の場合は文字数を赤字で警告表示
- ディスクリプションが160文字超の場合は文字数を赤字で警告表示
- 競合一覧テーブルは縞模様で見やすく
- 全体的にカード型UIに整える

### ステップ5(任意):改善・追加機能

余裕があれば以下を追加する。


以下の機能を追加してください。

1. 検索結果のキャッシュ
   - 同じキーワード・URLの組み合わせで再検索した場合、APIを叩かずにキャッシュを使う
   - キャッシュはブラウザのセッション内のみで保持

2. コピーボタン
   - 結果をクリップボードにコピーできるボタンを追加

3. URLの入力補完
   - 「https://」を先頭に自動補完する

## APIキーの差し込み方

1. Claudeが生成した `seo-checker.html` をテキストエディタで開く
2. `YOUR_API_KEY_HERE` を検索する
3. 実際のAPIキー文字列に書き換えて保存する
4. Google Chromeでファイルを開いて動作確認する

⚠️ APIキーが含まれたHTMLファイルを他者に共有・公開しないこと

## 動作確認チェックリスト

- [ ] URLとキーワードを入力してボタンを押すとローディングが表示される
- [ ] 数秒後に結果が表示される
- [ ] 対象URLが検索結果に含まれる場合、順位・タイトル・ディスクリプションが表示される
- [ ] 対象URLが含まれない場合、「上位10件に表示されていません」と表示される
- [ ] 上位10件の競合一覧が表示される
- [ ] コンソールにエラーが出ていない

## トラブルシューティング

| 症状 | 原因と対処 |
|---|---|
| APIエラー(401) | APIキーが正しく設定されていない |
| APIエラー(CORS) | CORSエラーの場合、SERP APIがCORSを許可しているか確認。多くのSERP APIはブラウザから直接呼び出し可能 |
| 結果が空 | `organic_results` のキー名をconsole.logで確認し、実際のレスポンス構造に合わせる |
| URLがマッチしない | 入力URLの末尾スラッシュや `www` の有無を確認。部分一致(`includes`)で判定するよう修正 |

## 提出物

- `seo-checker.html`(APIキーは削除または伏せた状態)
- 使用したプロンプトの一覧(本手順書のステップ1〜4)
- 開発の流れの説明(口頭または文章)

④ 手順書に沿ってHTML出力を依頼

手順書に沿ってHTML出力をお願いします

→ 一発でUI・API連携・結果表示・デザインまで含んだHTMLが生成された


つまづいたポイント

① APIサービスの特定
初回実行時、API読み込みエラーが出てしまった。エラーをAIに読み込ませたところ、キーはSerpApiのものだったにも関わらず、ValueSERPのエンドポイントで実装してしまっていたことが判明しました。キーの形式だけでは判断できず、ブラウザで直接叩いて確認することで特定。
→ 事前に「どのSERPサービスか」を明示できていれば防げた問題。

https://serpapi.com/search?api_key=xxxxx&q=test&engine=google

⚠️ APIキーの取り扱いには注意

APIキーをそのままAIに読み込ませると、意図せず外部に共有されるリスクがあります。万が一流出した場合、第三者による不正利用や、API使用量(トークン)の消費につながる可能性があります。
そのため、AIにコードやファイルを渡して相談する際は、必ずAPIキーを削除またはマスクした状態で実行するようにしてください。

② CORSエラー

SerpApiはブラウザから直接呼び出せない仕様のため、file://でもlocalhost経由でもCORSブロック(ブラウザが勝手に外部に通信するのを防ぐ)が発生。
→ PythonのプロキシサーバーをHTMLとSerpApiの間に挟むことで解決。

③ キャッシュ問題

基礎的だが、HTMLを修正してもブラウザが古いコードをキャッシュしていて変更が反映されなかった。
→ キャッシュをクリアにして再度実行

気づき

つまづきはすべて環境・アーキテクチャ上の問題。Claudeの実装能力の問題ではなく、「どんなAPIか」「ブラウザから直接叩けるか」という事前の要件確認の精度の話だった。
また、エラーメッセージをそのままClaudeに渡すのが一番早かった。原因の説明から解決策まで一緒に出してくれるので、「何が起きているかわからない」状態でも前に進めた。

②:Qiita自動いいね機能

仕様

Claude in Chromeを使い、自社のQiita記事一覧ページを開いて上から3件の記事に順番にいいねを押す。いいね済みの記事はスキップ。ショートカットコマンドで毎回実行できる状態にする。

条件 処理
いいね未済(aria-pressed="false" いいねボタンをクリック
いいね済み(aria-pressed="true" スキップ
自分の記事(ボタンがdisabled スキップ

プロンプトのラリー概要

① タスク分解を依頼

プロンプト

Claude in Chromeを使って以下を自動で行いたい。タスクを分解して。
順番に上から3件の記事を調べ、順番にいいねを押していく
注意点として、いいねを押してあった場合はスキップするようにする

結果

タスク1:「コマンド化」の手段を決める(Claude in Chromeのショートカット機能を使う)
タスク2:処理フローを設計する
タスク3:Claude in Chromeで手動1回実行して動作確認する
タスク4:ショートカットとして登録する

② Chrome上で直接プロンプトを入力して動作確認

以下の手順をすべて実行してください。
- https://qiita.com/organizations/visionary-jp/items を開く
- 上から3件の記事を順番に開き、いいね未済ならいいねする
- いいね済み・自分の記事はスキップ
- 完了後に結果レポートを出力する

上位3件が自動でいいねされた
image.png

③ ショートカットの登録場所がわからない
Claude in Chrome のどこからショートカットを登録するかわからなかったため確認。サイドパネルの入力欄にある / アイコンから設定画面に入り、コマンド名とプロンプトを登録する流れを把握した。

④ ショートカット登録
手動実行時にストックボタンを誤クリックしていたため、プロンプトに制約を追加するようお願いした。
その内容を以下のように、ショートカット登録した。

いいねボタン以外(ストック・コメントなど)は一切触らないこと

以下の手順をすべて実行してください。
- https://qiita.com/organizations/visionary-jp/items を開く
- 上から3件の記事を順番に開き、いいね未済ならいいねする
- いいね済み・自分の記事はスキップ
- **いいねボタン以外(ストック・コメントなど)は一切触らないこと**
- 完了後に結果レポートを出力する
Claude in Chrome の設定画面から /qiita-like というコマンド名でこのプロンプトを登録。以降は入力欄に /qiita-like と打つだけで実行できる。

✅ 完了レポート
・1位:【Docker】実務でよく使うDockerコマンドまとめ + よくあるエラーと対処法
 → いいねしました
・2位:n8nとは?ノーコードで業務自動化できる最強ツールを解説
 → いいねしました
・3位:AI時代に実装だけでは足りないと気づいた話
 → スキップ(自分の記事のためいいね不可)

3件中 2件いいねしました。

ショートカット実行時(/qiita-like を入力)

image.png

いいね実施と完了レポートを表示(仕様上自アカウウントはいいねできないためスキップしている。)
image.png


ヒヤリとした場面

画像では成功パターンだが、何回か実行する中で、Claudeが処理中に誤ってストックボタン周辺をクリックしてしまい、指定していないページにとび、勝手に「あとで読む」に追加されてしまった。指示の曖昧さがそのまま挙動の曖昧さになることを実感した場面だった。「いいねボタン以外(ストック・コメントなど)は一切触らないこと」と追加したことで、この現象は見られなくなった。


まとめ

良かったこと

  • 「何をしたいか」を伝えるだけで、UI・ロジック・デザインまで一気に生成できる
  • タスクを分解してからプロンプトを書くと、精度が上がる
  • 手順書をClaudeに作らせてから実装させると、再現性が高まる
  • エラーメッセージをそのままClaudeに渡すのが一番早かった。原因の説明から解決策まで一緒に出してくれるので、「何が起きているかわからない」状態でも前に進めた。

注意が必要だったこと

  • APIの仕様(CORSの可否など)は事前に把握しておく
  • 指示が曖昧だと、意図しない操作をすることがある
  • ブラウザキャッシュや環境起因の問題はClaudeとは別レイヤーで対処が必要

Claudeへのプロンプトは「何をしてほしいか」が曖昧なままだと、出力も曖昧になる。要件定義の精度がそのまま成果物の精度になるということを実感しました。
また、セキュリティまわりはまだ理解が浅い部分も多く、今回の実装も完璧とは言えません。APIキーの管理方法や公開範囲については今後も継続して学んでいく必要があると感じています。記事内の情報も随時アップデートしていく予定です。
今回はClaudeを使った開発を中心に行いましたが、
今後はさらに一歩踏み込み、Claude Codeを使った開発フローにも挑戦したいと考えています。特に、

  • コード生成だけでなく「構成」や「設計」まで任せられるか
  • 実務レベルでどこまで活用できるか

といった観点で検証していきたいと思います。

29
9
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
29
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?