1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google Custom Search APIを使った商品検索ツール開発メモ (Docker + Python)

Posted at

Google Custom Search APIを使った商品検索ツール開発メモ (Docker + Python)

概要

Google Custom Search APIを用いて、商品名をキーワードにウェブ検索し、その結果をExcelファイルとして出力するツールの開発メモです。
Pythonスクリプトで処理を実装し、Dockerで環境構築・実行までを行いました。
本記事では、開発中に直面した問題点やトラブルシューティングについてもまとめます。

やりたいこと

  • 任意のキーワード(商品名)でGoogle Custom Search APIを用いたウェブ検索
  • 検索結果(URL, タイトル, 概要)をExcelファイル(search_results.xlsx)に出力
  • Dockerコンテナ内でスクリプト実行 → ホスト側に結果を取得

使用技術・サービス

環境構築フロー

  1. Google Custom Search APIキーとCX取得

    • Google Cloud Platformでプロジェクト作成
    • Programmable Search Engineでウェブ全体検索が可能なCSEをセットアップ(*で全サイト検索)
    • APIキーとCXを控える
  2. Pythonスクリプト作成
    py/search_export.py (例)

    import requests
    import pandas as pd
    import argparse
    
    def main():
        parser = argparse.ArgumentParser(description="Google Custom Search Script")
        parser.add_argument("--api_key", required=True, help="Google Custom Search API key")
        parser.add_argument("--cx", required=True, help="Custom Search Engine ID")
        parser.add_argument("--query", required=True, help="Search query")
    
        args = parser.parse_args()
    
        API_KEY = args.api_key
        CX = args.cx
        query = args.query
    
        url = "https://www.googleapis.com/customsearch/v1"
        params = {
            "key": API_KEY,
            "cx": CX,
            "q": query,
            "hl": "ja",
            "lr": "lang_ja"
        }
    
        response = requests.get(url, params=params)
        data = response.json()
    
        items = data.get("items", [])
        results = []
        for item in items:
            title = item.get("title")
            link = item.get("link")
            snippet = item.get("snippet")
            results.append({"Title": title, "URL": link, "Description": snippet})
    
        df = pd.DataFrame(results)
        df.to_excel("search_results.xlsx", index=False)
    
    if __name__ == "__main__":
        main()
    
    

3. Dockerfile作成 (docker/Dockerfile)

FROM python:3.11
WORKDIR /app
COPY py/search_export.py /app/
RUN pip install requests pandas openpyxl
CMD ["python", "search_export.py"]

ディレクトリ構成例:

product-usage-web-scraper/
  ├─ docker/
  │   └─ Dockerfile
  └─ py/
     └─ search_export.py

4. ビルド・実行例

cd product-usage-web-scraper
docker build -f docker/Dockerfile -t product-usage-web-scraper .
docker run -it product-usage-web-scraper python search_export.py \
    --api_key "YOUR_API_KEY" --cx "YOUR_CX" --query "牛丼"

5. 結果ファイル取得

バックグラウンド実行してコンテナID取得後にコピー:

docker run -d product-usage-web-scraper python search_export.py \
    --api_key "YOUR_API_KEY" --cx "YOUR_CX" --query "牛丼"
docker ps -a
# 最新のCONTAINER_IDを控える
docker cp <CONTAINER_ID>:/app/search_results.xlsx .

トラブルシューティング

CSE設定なのに期待した結果が出ない

  • 原因: CSEが特定サイト限定になっている可能性
  • 対策: *を指定し全サイト検索可能にする。hl=jalr=lang_jaを付与して日本語検索を最適化

docker buildでCOPY失敗

  • 原因: ビルドコンテキストとファイルパスの不一致
  • 対策: docker buildproduct-usage-web-scraperディレクトリで実行し、COPY py/search_export.py /app/を正しく指定

シェルスクリプト実行時not foundエラー

  • 原因: Windows由来のCRLF改行コードが原因でUNIXシェルが正しく解釈できない
  • 対策: dos2unixコマンドでLF改行へ変換する

ファイル未生成(docker cpでファイルなし)

  • 原因: スクリプトエラーやitemsが空でsearch_results.xlsx未作成
  • 対策: docker logs <CONTAINER_ID>でログ確認
    print(response.json())をコードに追加しAPIレスポンスをチェック
    APIキー・CX・CSE設定を再確認

結果が10件までしか取得できない

  • 原因: Custom Search APIは1リクエスト最大10件まで
  • 対策: startパラメータを用いてページングし、複数回リクエストで件数拡張

料金について

  • 1日100クエリまでは無料
  • 超過分は1,000クエリあたり約5ドル程度 (最新情報要確認)

まとめ

  • Docker+PythonでGoogle Custom Search APIを利用し、ウェブ検索結果をExcel出力する一連のフローを構築
  • 開発中の各種トラブル(改行コード、CSE設定、APIレスポンス確認)への対処法を記録
  • 今後はエラー処理強化やページング対応などで機能拡張可能

これらの知見が、同様の開発を行う際の参考になれば幸いです。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?