commit 71cb145(2026-11-12 16:15) crawler_visits:bot を指定したとき、1回ずつの訪問(日本時間の時刻・ページ)を hits に返す(Claude-User の読みがエイイチ・Claude の試しかを時刻で突き合わせるため) diff --git a/worker/index.js b/worker/index.js index bbe919f..e327cdb 100644 --- a/worker/index.js +++ b/worker/index.js @@ -593,7 +593,7 @@ async function crStats(request, env, url) { if (!m.b) continue; const day = o.key.split('/')[1]; if (since && day < since) continue; - rows.push({ ...m, day, week: evWeekOf(day) }); + rows.push({ ...m, day, week: evWeekOf(day), at: Number(o.key.split('/')[2].split('-')[0]) || 0 }); } cursor = r.truncated ? r.cursor : undefined; if (++pages >= 40 && cursor) { truncated = true; break; } @@ -644,6 +644,11 @@ async function crStats(request, env, url) { byVia: [...viaMap.values()].sort((a, b) => b.visits - a.visits).map((e) => ({ via: e.via, visits: e.visits, records: e.records.size, bots: [...e.bots].sort((a, b) => b[1] - a[1]).map(([b, n]) => `${b} ${n}`).join('、'), last: e.last })), byViaWeek: [...viaWeeks].sort((a, b) => b[0].localeCompare(a[0])).map(([week, m]) => ({ week, total: [...m.values()].reduce((x, y) => x + y, 0), via: [...m].sort((a, b) => b[1] - a[1]).map(([v, n]) => `${v} ${n}`).join('、') })), errors: [...errMap.values()].sort((a, b) => b.visits - a.visits).slice(0, 100).map((e) => ({ path: e.path, status: e.status, visits: e.visits, bots: [...e.bots].join('、'), last: e.last })), + // ?bot= のときは1回ずつの訪問(日本時間の時刻・ページ・「AIで読む」の印・結果)を新しい順に200件まで。 + // エイイチや Claude の作業の時刻と突き合わせて、試しの分かどうかを見分けるため(2026-11-12) + ...(only ? { hits: scope.filter((r) => r.at).sort((a, b) => b.at - a.at).slice(0, 200).map((r) => ({ + at: new Date(r.at + 9 * 3600e3).toISOString().slice(0, 19).replace('T', ' '), path: r.p, via: r.v || '', status: r.s, verified: r.ok, + })) } : {}), }; if (url.searchParams.get('format') === 'json') { return new Response(JSON.stringify(data), { headers: { 'content-type': 'application/json; charset=utf-8', 'x-robots-tag': 'noindex', 'cache-control': 'no-store' } }); diff --git a/worker/mcp.js b/worker/mcp.js index c20a9c3..b19e7d1 100644 --- a/worker/mcp.js +++ b/worker/mcp.js @@ -70,7 +70,7 @@ const TOOLS = [ description: 'どのクローラーが・どのページを読んだか(/api/cr-stats)。返せなかったページ(400以上)も。長い期間を指定すると一部しか数えない(truncated)ので、since は2週間以内にする。', inputSchema: { type: 'object', properties: { since: { type: 'string', description: 'この日以降(YYYY-MM-DD)。省略すると7日前' }, - bot: { type: 'string', description: 'ページごとの表をこのクローラーだけに(例 ChatGPT-User)' }, + bot: { type: 'string', description: 'ページごとの表をこのクローラーだけに(例 ChatGPT-User)。指定すると1回ずつの訪問(日本時間の時刻・ページ)も hits に返す' }, } }, annotations: { readOnlyHint: true, openWorldHint: false }, }, commit b1a185a(2026-11-12 16:18) how_to_read:AI の依頼読みが試しの分かは、hits の時刻とチャットの履歴を突き合わせて確かめる(11/3 の Claude-User 12件は LOG437 の試しと確認) diff --git a/worker/mcp.js b/worker/mcp.js index b19e7d1..540b70d 100644 --- a/worker/mcp.js +++ b/worker/mcp.js @@ -24,7 +24,7 @@ const GUIDE = `# Pixels to Motors(pixelstomotors.com)のサイトの計測 ## 混ざりうるもの(数を読む前に必ず思い出す) - aiReads の viaButton は記事の「AIで読む」ボタン経由。エイイチや Claude の試しが混ざりうる。ボタンの利用そのものは site_usage の押したもの(btn:AIで読む・場所 ai)で人のクリックを見る。crawler_visits の byVia は Amazonbot などのクローラーがボタンの行き先をたどった分が大半で、利用の数としては使えない(2026-11-05 に判明) -- aiReads には、エイイチ自身が ChatGPT・Claude にこのサイトのことを聞いた分も入りうる(見分けられない)。トップ(/)が多い日はそれを疑う +- aiReads には、エイイチ自身が ChatGPT・Claude にこのサイトのことを聞いた分も入りうる。名乗りだけでは見分けられないので、crawler_visits に bot(例 Claude-User)を指定して hits の時刻を出し、エイイチ・Claude の作業の時刻(チャットの履歴)と突き合わせて確かめる。「混ざりうる」で済ませない(2026-11-12)。例:11/3 09:26〜09:29 の Claude-User 12件は、LOG437 で TOP の「AIで読む」を Claude で試した分だった - Claude のセッションが WebFetch でサイトを読むと Claude-User として入りうる - 人の数は 2026-10-26 から(それより前は人と機械を分けていない)。人の表示の約9割は機械なので、来訪の数は必ず人だけ(who=human)で見る - エイイチ・Claude の確認の閲覧は ?p2m-notrack=1 を付けたブラウザでは送られない。付け忘れた自動のブラウザは navigator.webdriver で機械に入る commit 1e04e85(2026-11-12 16:34) how_to_read:Claude の作業のセッションの WebFetch は Claude-User に入っていないことを記す diff --git a/worker/mcp.js b/worker/mcp.js index 540b70d..de00bcf 100644 --- a/worker/mcp.js +++ b/worker/mcp.js @@ -25,7 +25,7 @@ const GUIDE = `# Pixels to Motors(pixelstomotors.com)のサイトの計測 ## 混ざりうるもの(数を読む前に必ず思い出す) - aiReads の viaButton は記事の「AIで読む」ボタン経由。エイイチや Claude の試しが混ざりうる。ボタンの利用そのものは site_usage の押したもの(btn:AIで読む・場所 ai)で人のクリックを見る。crawler_visits の byVia は Amazonbot などのクローラーがボタンの行き先をたどった分が大半で、利用の数としては使えない(2026-11-05 に判明) - aiReads には、エイイチ自身が ChatGPT・Claude にこのサイトのことを聞いた分も入りうる。名乗りだけでは見分けられないので、crawler_visits に bot(例 Claude-User)を指定して hits の時刻を出し、エイイチ・Claude の作業の時刻(チャットの履歴)と突き合わせて確かめる。「混ざりうる」で済ませない(2026-11-12)。例:11/3 09:26〜09:29 の Claude-User 12件は、LOG437 で TOP の「AIで読む」を Claude で試した分だった -- Claude のセッションが WebFetch でサイトを読むと Claude-User として入りうる +- Claude の作業のセッション(Claude Code の WebFetch)がサイトを読んでも、Claude-User には入っていない(11/8 に LOG476 のチャットが /serving-robot-one-less-staff を WebFetch したが、その日の Claude-User は0件。2026-11-12 に確認)。Claude-User に入るのは claude.ai のチャットでの読み(「AIで読む」ボタンを含む) - 人の数は 2026-10-26 から(それより前は人と機械を分けていない)。人の表示の約9割は機械なので、来訪の数は必ず人だけ(who=human)で見る - エイイチ・Claude の確認の閲覧は ?p2m-notrack=1 を付けたブラウザでは送られない。付け忘れた自動のブラウザは navigator.webdriver で機械に入る - crawler_visits(/api/cr-stats)は長い期間を指定すると記録が多すぎて一部しか数えない(truncated が true)。2026-10-25 からの合計は少なめに出ていた。日ごとの数は kpi(日ごとに集計して残したもの)で見る commit 8af4e01(2026-11-12 18:58) 計測:?p2m-notrack=1 を覚えられないブラウザでも、その表示は送らない/読み方の説明を Codex の検証(11/12)に合わせて直す(依頼読みは取得の回数・WebFetch は未確認・日ごとの集計の抜けと二重) diff --git a/src/components/SiteMeasure.astro b/src/components/SiteMeasure.astro index 1bea227..59ebf8b 100644 --- a/src/components/SiteMeasure.astro +++ b/src/components/SiteMeasure.astro @@ -32,6 +32,8 @@ if (q === '0') localStorage.removeItem(OPT); off = localStorage.getItem(OPT) === '1'; } catch { saved = false; /* 覚えられない環境では、送るかどうかを毎回の判定だけで決める */ } + // 覚えられない環境でも、?p2m-notrack=1 で開いたその表示は送らない(2026-11-12 Codex の指摘:例外のとき除外が効かなかった) + if (q === '1') off = true; const nav = navigator as Navigator & { globalPrivacyControl?: boolean }; const dnt = nav.doNotTrack === '1' || nav.globalPrivacyControl === true; if (dnt) off = true; diff --git a/worker/mcp.js b/worker/mcp.js index de00bcf..49ca4d1 100644 --- a/worker/mcp.js +++ b/worker/mcp.js @@ -18,14 +18,14 @@ const GUIDE = `# Pixels to Motors(pixelstomotors.com)のサイトの計測 ## いま主に見る3つの数字(2026-11-06 にエイイチが決めた) サイトのねらい:AI に調べられることで、人の来訪や知名度がいつ増えはじめるかを見る。サイトはもともと検索で人を集める作りにしていない。 -1. AI の利用者の依頼で読みに来た数(aiReads):ChatGPT-User・Claude-User・Perplexity-User・MistralAI-User が読んだページの数。/robots.txt は数えない。ChatGPT-User のうち Cloudflare が本物と確かめられなかったものは入れず、unverifiedChatGPTExcluded に別に数える。Claude-User は Cloudflare が確かめないので全部入れる +1. AI の利用者の依頼で読みに来た数(aiReads):ChatGPT-User・Claude-User・Perplexity-User・MistralAI-User のページの取得の回数(ページの数・依頼の数・人数ではない。同じページを2回取れば2件、/llms.txt も入る)。/robots.txt は数えない。ChatGPT-User のうち Cloudflare が本物でないとしたもの(ok=0)は入れず unverifiedChatGPTExcluded に別に数える(判定がないもの ? は入る)。Claude-User は Cloudflare が確かめないので全部入る。名乗りは偽れるので、本物かどうかは確かめていない 2. AI のサービスのリンクから来た人の数(aiReferrals):referrer が chatgpt.com などか、リンクの印 utm_source が chatgpt.com などの表示のうち、人の操作(マウス・指・キー)があったものだけ。機械・操作なしは notHumanExcluded に別に数える 3. サイト名で検索して来た人の数(nameSearch):Search Console のサイト名(Pixels to Motors・pixelstomotors など)の検索のクリック数。今は週の分析のときに Claude が Search Console(Chrome 拡張・新旧ドメインの両方)を見て、record_name_search で週ごとに書き足す(2026-11-06 決定。API の自動取得は Google Workspace の組織のポリシーでサービスアカウントの鍵が作れず保留。鍵 GSC_SA_KEY を入れれば毎日自動に切り替わる)。数は2〜3日遅れて確定し、人数の少ない検索語は Search Console が伏せるので少なめに出る。kpi の nameSearch に週ごとの記録(byDay・検索語・検索全体のクリック allClicks)が出る ## 混ざりうるもの(数を読む前に必ず思い出す) - aiReads の viaButton は記事の「AIで読む」ボタン経由。エイイチや Claude の試しが混ざりうる。ボタンの利用そのものは site_usage の押したもの(btn:AIで読む・場所 ai)で人のクリックを見る。crawler_visits の byVia は Amazonbot などのクローラーがボタンの行き先をたどった分が大半で、利用の数としては使えない(2026-11-05 に判明) - aiReads には、エイイチ自身が ChatGPT・Claude にこのサイトのことを聞いた分も入りうる。名乗りだけでは見分けられないので、crawler_visits に bot(例 Claude-User)を指定して hits の時刻を出し、エイイチ・Claude の作業の時刻(チャットの履歴)と突き合わせて確かめる。「混ざりうる」で済ませない(2026-11-12)。例:11/3 09:26〜09:29 の Claude-User 12件は、LOG437 で TOP の「AIで読む」を Claude で試した分だった -- Claude の作業のセッション(Claude Code の WebFetch)がサイトを読んでも、Claude-User には入っていない(11/8 に LOG476 のチャットが /serving-robot-one-less-staff を WebFetch したが、その日の Claude-User は0件。2026-11-12 に確認)。Claude-User に入るのは claude.ai のチャットでの読み(「AIで読む」ボタンを含む) +- Claude の作業のセッション(Claude Code の WebFetch)の読みが Claude-User に入るかは確かめていない(11/8 の1回は対応する記録が見つからなかったが、それだけで入らないとは言えない。2026-11-12 Codex の指摘)。だれの読みかは、時刻とチャットの履歴が合ったものだけを「試し」と言い、合わないものは「未確認」と書く(外の人とも言わない) - 人の数は 2026-10-26 から(それより前は人と機械を分けていない)。人の表示の約9割は機械なので、来訪の数は必ず人だけ(who=human)で見る - エイイチ・Claude の確認の閲覧は ?p2m-notrack=1 を付けたブラウザでは送られない。付け忘れた自動のブラウザは navigator.webdriver で機械に入る - crawler_visits(/api/cr-stats)は長い期間を指定すると記録が多すぎて一部しか数えない(truncated が true)。2026-10-25 からの合計は少なめに出ていた。日ごとの数は kpi(日ごとに集計して残したもの)で見る @@ -45,7 +45,7 @@ const TOOLS = [ { name: 'kpi', title: '3つの数字(日ごと・週ごと)', - description: 'いま主に見る3つの数字を返す:AI の利用者の依頼で読みに来た数・AI のサービスのリンクから来た人の数・サイト名で検索して来た人の数(Search Console から記録した分)。日ごとに集計して残したものなので速く、数え漏れがない。混ざりうるものは how_to_read を読むこと。日付は日本時間、週は月曜はじまり。', + description: 'いま主に見る3つの数字を返す:AI の利用者の依頼で読みに来た数・AI のサービスのリンクから来た人の数・サイト名で検索して来た人の数(Search Console から記録した分)。日ごとに集計して残したものなので速い。ただし作ったあとに届いた記録は入らず、0時をまたいで送り直された表示は2日に1件ずつ数えることがある(2026-11-12 Codex の指摘・未修正)。混ざりうるものは how_to_read を読むこと。日付は日本時間、週は月曜はじまり。', inputSchema: { type: 'object', properties: { since: { type: 'string', description: '始めの日(YYYY-MM-DD)。省略すると28日前。2026-10-26 より前は数えない' }, until: { type: 'string', description: '終わりの日(YYYY-MM-DD)。省略すると今日(今日は途中の数)' },