問題の概要
Google Sheetsで次のような数式を使用しているとします:
=IMPORTDATA("https://example.com/data.csv")
データが読み込まれる代わりに、セルに以下のエラーが表示されます:
Could not fetch url: https://example.com/data.csv
Google SheetsはそのURLへのアクセスを試みましたが、失敗しました。URLがGoogleのサーバーから到達できない、リソースが存在しない、またはサーバーがリクエストを拒否したことが原因として考えられます。
原因
多くの人が見落としがちな重要な点として、Google SheetsはURLをGoogleのサーバーから取得しており、あなたのブラウザからではありません。ChromeでURLが正常に開けても、Sheetsでは失敗する場合があります。原因はいくつかのカテゴリに分類されます:
- URLに認証が必要 — プライベートなAPIエンドポイント、トークンで保護されたリソース、ログインが必要なページはすべて失敗します。
- サーバーがGoogleのIPレンジをブロックしている — GoogleのデータセンターIPブロック(例:66.249.x.x)からのリクエストを拒否するボットブロックルールを持つサーバーがあります。
- コンテンツタイプが不正 — IMPORTDATAはプレーンなCSVまたはTSVのみを処理します。JSON、XML、HTMLページを指定すると常にエラーになります。
- 無効または期限切れのURL — タイプミス、リンク切れ、または15分後に期限切れになった署名付きURLはすべてSheetsには同じように見えます。
- リダイレクトチェーン — リダイレクトが多すぎる場合や、SheetsがフォローできないHTTP→HTTPSリダイレクトが原因になることがあります。
- サーバー側のボットブロック — ブラウザ以外のUser-Agent文字列を明示的に拒否するサービスがあります。
まず確認すること
1. URLが本当に公開されているか確認する
シークレットウィンドウ(Cookie・セッションなし)でURLを開いてみてください。ログインページが表示されたり403が返される場合、それが原因です。Google Sheetsは匿名訪問者と全く同じものを見ています。
2. curlでブラウザ以外のリクエストをシミュレートする
curl -I "https://example.com/data.csv"
403 Forbiddenまたは401 Unauthorizedが返される場合、サーバーがブラウザ以外のクライアントをブロックしています。Google Sheetsも同じ壁にぶつかります。
3. サーバーが返すコンテンツタイプを確認する
curl -s -o /dev/null -w "%{content_type}" "https://example.com/data.csv"
IMPORTDATAはtext/csvまたはtext/tab-separated-valuesを期待しています。application/jsonやtext/htmlが表示される場合は、適切なインポート関数に切り替えてください(後述の修正方法4を参照)。
原因別の修正方法
修正方法1:直接アクセス可能な公開CSV/TSV URLを使用する
URLはログインやトークンなしで公開アクセス可能で、生のCSVまたはTSVを返す必要があります。GitHubのrawファイルURLが信頼性の高い例です:
=IMPORTDATA("https://raw.githubusercontent.com/user/repo/main/data.csv")
注意:rawのURLを使用してください。ファイルプレビューページはCSVではなくHTMLを返します。
修正方法2:Google Drive — エクスポートURLを使用する
Google SheetsまたはDrive上のデータを使用する場合は、エクスポートエンドポイントを直接使用してください:
=IMPORTDATA("https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/export?format=csv&gid=SHEET_GID")
SPREADSHEET_IDとSHEET_GIDを実際の値に置き換えてください。ソーススプレッドシートは「リンクを知っている全員が閲覧可能」として共有されている必要があります。そうでないと、403エラーが返されます。
修正方法3:サーバーがGoogleをブロックしている場合 — リクエストをプロキシする
データソースを管理している場合は、GoogleのIPレンジをホワイトリストに追加するか、そのエンドポイントのボットブロックルールを緩和してください。サーバーを管理していない場合は、2つの選択肢があります。
オプションA:公開CORSプロキシ経由でルーティングする(機密性のない公開データのみ)。オプションB:小規模なミドルウェアサービスを構築する:
# 最小限のFlaskプロキシ
from flask import Flask, Response, request
import requests
app = Flask(__name__)
@app.route("/proxy")
def proxy():
url = request.args.get("url")
r = requests.get(url)
return Response(r.content, content_type="text/csv")
その後、Sheetsを自分のエンドポイントに向けます:
=IMPORTDATA("https://yourproxy.com/proxy?url=https://example.com/data.csv")
修正方法4:CSV以外のソースには関数を切り替える
IMPORTDATAはCSVとTSVのみ対応しています。URLがHTMLやXMLを返す場合は、別の関数が必要です:
=IMPORTHTML("https://example.com/table-page", "table", 1)
=IMPORTXML("https://example.com/feed.xml", "//item/title")
修正方法5:キャッシュされたエラーを強制クリアする
URLが再びアクセス可能になった後でも、Sheetsが取得エラーをキャッシュしてしまうことがあります。強制的に再読み込みする方法は2つあります:
- URLにダミーパラメータを追加する:
?t=1を?t=2に変更して強制的に再評価させる。 - ファイル → 設定 → 計算 → 変更時および毎時に移動して、定期的な更新をトリガーする。
=IMPORTDATA("https://example.com/data.csv?nocache=" & TEXT(NOW(), "YYYYMMDDHHMMSS"))
NOW()を使ったトリックはデバッグに有効です。シートが変更されるたびに再計算されます。データが正しく読み込まれたら削除してください。そのままにしておくと、キーを押すたびにサーバーへのリクエストが発生します。
根本的な解決策 — 信頼性の高い場所にデータをホストする
IMPORTDATAがワークフローの中心的な機能である場合は、匿名の公開アクセス向けに設計された場所にCSVを配置してください:
- GitHubのrawURL — 無料、公開リポジトリには認証不要、安定して信頼性が高い
- Google Drive + エクスポートURL — 上記の
/export?format=csvパターンを公開共有で使用 - AWS S3パブリックバケット — オブジェクトACLを
public-readに設定して、直接のS3 URLを使用 - Cloudflare R2 — 同様の仕組みで、トラフィックの多いファイルはS3より安価なエグレスコスト
修正の確認
- 数式またはURLを更新し、Sheetsがデータを取得するまで10〜15秒待ちます。
- エラーが表示されていたセルが実際のデータ行に置き換わるはずです。
- インポートされた範囲のセルA1を確認します — CSVヘッダーの最初のフィールドが表示されているはずです。
- 取得エラーの代わりに
#N/Aが表示されている場合は、URLは読み込まれましたがデータ形式に問題があります — 区切り文字の設定やファイルにBOM文字が含まれていないか確認してください。
正しい公開URLを使用しても失敗し続ける場合は、ローカルネットワーク外のサーバーから新しいcurlリクエストを実行してみてください。URLが本当に公開されているのか、それとも自分のIPレンジからのみアクセス可能なのかを確認できます。

