<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Google Search Console on kenji.blog</title><link>http://kenji.blog/zh-tw/tags/google-search-console/</link><description>Recent content in Google Search Console on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 12:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/zh-tw/tags/google-search-console/index.xml" rel="self" type="application/rss+xml"/><item><title>工程師為了增加技術部落格月流量應該做的事</title><link>http://kenji.blog/zh-tw/p/tech-blog-growth-strategies-for-engineers/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/zh-tw/p/tech-blog-growth-strategies-for-engineers/</guid><description>&lt;img src="http://kenji.blog/p/tech-blog-growth-strategies-for-engineers/img/eyecatch.jpg" alt="Featured image of post 工程師為了增加技術部落格月流量應該做的事" />&lt;h2 id="前言正因為是工程師才能做到的技術部落格成長駭客">前言：正因為是工程師才能做到的技術部落格成長駭客
&lt;/h2>&lt;p>許多軟體工程師都會開設技術部落格，但能聚集一定瀏覽量，並長期間維持與擴大流量的例子卻不多。寫出高品質的技術文章是大前提，但「只要寫出好文章自然就會有人看」的時代已經結束了。現在的搜尋引擎演算法變得非常複雜，而且社群網路上的資訊流動速度也比以往任何時候都要快。&lt;/p>
&lt;p>然而，工程師擁有其他職位所沒有的優勢。那就是「理解系統架構、能組合工具進行自動化、能用程式分析數據」。本文將不只停留在單純的寫作技巧，而是將技術部落格視為一個「產品」，極度詳細且實踐性地解說如何利用工程能力來大幅提升月流量的策略。&lt;/p>
&lt;hr>
&lt;h2 id="1-面向工程師的技術部落格seo架構">1. 面向工程師的技術部落格SEO架構
&lt;/h2>&lt;p>作為部落格基礎的系統（如靜態網站生成器）和HTML結構，是搜尋引擎正確理解內容的最重要項目。&lt;/p>
&lt;h3 id="11-core-web-vitals-的最佳化">1.1 Core Web Vitals 的最佳化
&lt;/h3>&lt;p>Google 採用頁面體驗作為排名因素，特別是 &lt;strong>Core Web Vitals (LCP, FID/INP, CLS)&lt;/strong> 在技術部落格中也無法忽視。
技術部落格經常大量使用原始碼區塊、數學公式（MathJax / KaTeX）和圖解圖片。這些都會成為延遲頁面渲染的因素。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>LCP (Largest Contentful Paint)&lt;/strong>: 首屏主要內容的載入速度。主視覺圖片應使用 WebP 或 AVIF，並加上 &lt;code>fetchpriority=&amp;quot;high&amp;quot;&lt;/code> 屬性進行預載入。此外，用於語法標明的巨大 CSS 或 JS 應設計為非同步載入，或僅在需要的頁面載入。&lt;/li>
&lt;li>&lt;strong>CLS (Cumulative Layout Shift)&lt;/strong>: 文章載入過程中的版面偏移。透過 CSS 的 &lt;code>aspect-ratio&lt;/code> 等預先保留數學公式和圖片的顯示區域，可以防止後續 DOM 插入時造成的畫面跳動。&lt;/li>
&lt;li>&lt;strong>INP (Interaction to Next Paint)&lt;/strong>: 對使用者操作的響應性。繁重的 JavaScript（例如客戶端的動態全文檢索或巨大的 Markdown 解析器執行等）不應在主執行緒上執行，必須轉移到 Web Worker，或者在建置時生成靜態 HTML (SSG)。&lt;/li>
&lt;/ul>
&lt;h3 id="12-結構化資料json-ld的實作">1.2 結構化資料（JSON-LD）的實作
&lt;/h3>&lt;p>為了明確地告訴搜尋引擎頁面是「文章」，作者是「誰」，需要實作 JSON-LD 格式的結構化資料。活用 &lt;code>TechArticle&lt;/code> 或 &lt;code>SoftwareSourceCode&lt;/code> 等 Schema，可以更容易顯示在 Google 的複合式搜尋結果中，從而提升 CTR（點閱率）。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;application/ld+json&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@context&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://schema.org&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;TechArticle&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;headline&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;工程師為了增加技術部落格月流量應該做的事&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;image&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;https://example.com/img/eyecatch.jpg&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;datePublished&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;2026-09-14T10:00:00+09:00&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;author&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Person&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Kenji&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://example.com/about/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;publisher&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Organization&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Kenji&amp;#39;s Tech Blog&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;logo&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;ImageObject&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://example.com/img/logo.png&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="13-語意化html與文件結構的最佳化">1.3 語意化HTML與文件結構的最佳化
&lt;/h3>&lt;p>標題（&lt;code>h1&lt;/code>〜&lt;code>h6&lt;/code>）的適當嵌套是基本中的基本，但在技術部落格中會被要求正確使用 HTML5 的語意標籤，如 &lt;code>article&lt;/code>, &lt;code>section&lt;/code>, &lt;code>aside&lt;/code>, &lt;code>nav&lt;/code>。此外，透過適當區分表示原始碼的 &lt;code>&amp;lt;code&amp;gt;&lt;/code> 和 &lt;code>&amp;lt;pre&amp;gt;&lt;/code>、表示鍵盤輸入的 &lt;code>&amp;lt;kbd&amp;gt;&lt;/code>、表示變數的 &lt;code>&amp;lt;var&amp;gt;&lt;/code> 等，可以提供機器可讀 (machine-readable) 的 HTML。這對於 AI 的內容索引（LLM 的學習資料收集或 RAG 系統）也是非常有效的手段。&lt;/p>
&lt;hr>
&lt;h2 id="2-搜尋意圖search-intent的心理學與關鍵字策略">2. 搜尋意圖（Search Intent）的心理學與關鍵字策略
&lt;/h2>&lt;p>要最大化來自搜尋引擎的流量（自然流量），必須準確解讀使用者「為什麼用那個關鍵字搜尋」的搜尋意圖。技術相關的搜尋意圖大致可分為兩類。&lt;/p>
&lt;h3 id="21-錯誤解決型與系統性學習評論型">2.1 「錯誤解決型」與「系統性學習・評論型」
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>錯誤解決型（Troubleshooting Intent）&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>搜尋關鍵字範例: &lt;code>Docker &amp;quot;no space left on device&amp;quot; 解決方案&lt;/code>, &lt;code>Python IndexError list index out of range 原因&lt;/code>&lt;/li>
&lt;li>心理: 因為開發中的錯誤而卡住，現在立刻需要能作為特效藥的指令或程式碼片段。&lt;/li>
&lt;li>策略: 在文章開頭（首屏）提示「結論（解決用的程式碼或指令）」。背景和詳細機制的解說放在後面，首先滿足使用者「想立刻修好」的渴望。這樣可以降低跳出率（Bounce Rate）。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>系統性學習・評論型（Learning &amp;amp; Review Intent）&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>搜尋關鍵字範例: &lt;code>React vs Vue 2026 比較&lt;/code>, &lt;code>Rust 非同步處理 入門&lt;/code>, &lt;code>GCP 網路架構 設計&lt;/code>&lt;/li>
&lt;li>心理: 想選擇新的技術堆疊，或想從基礎加深理解，已經準備好花時間閱讀。&lt;/li>
&lt;li>策略: 充實目錄（TOC），大量使用圖解或架構圖（如 Mermaid 等）。客觀比較優缺點，並包含在實際業務中如何使用的案例，可以延長停留時間。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="22-流量的指數衰減模型與長尾策略">2.2 流量的指數衰減模型與長尾策略
&lt;/h3>&lt;p>技術文章的瀏覽量，通常在公開後會因為在 SNS 等被瘋傳而形成高峰（Spike），隨後呈現指數型減少的趨勢。這個流量 $V(t)$ 可以用以下數學模型來近似：&lt;/p>
$$ V(t) = V_0 e^{-\lambda t} + C $$&lt;p>這裡的：&lt;/p>
&lt;ul>
&lt;li>$V(t)$: 時間 $t$ 的流量&lt;/li>
&lt;li>$V_0$: 公開後因 SNS 瘋傳等造成的初期流量高峰值&lt;/li>
&lt;li>$\lambda$: 伴隨內容過時或 SNS 上被遺忘的衰減常數（取決於技術趨勢變化的速度）&lt;/li>
&lt;li>$C$: 來自搜尋引擎的穩定自然搜尋流量（基準線流量）&lt;/li>
&lt;/ul>
&lt;p>要長期提升流量的關鍵，與其瞄準短暫的爆紅（$V_0$），不如將重點放在&lt;strong>如何將常數項 $C$（來自搜尋引擎的持續流量）最大化&lt;/strong>。涵蓋大量像特定的小眾錯誤、或是特定工具之間的串接方法等，即使搜尋量少但沒有競爭對手的「長尾關鍵字」，來將 $C$ 的總和培育成巨大的流量。&lt;/p>
&lt;hr>
&lt;h2 id="3-使用-google-search-console-api-的數據驅動內容分析">3. 使用 Google Search Console API 的數據驅動內容分析
&lt;/h2>&lt;p>為了建構穩定的流量基礎 $C$，必須活用 Google Search Console (GSC) 的數據，客觀地分析「被 Google 給予了什麼樣的評價」。然而，在 GSC 的 Web UI 上點擊操作是有極限的。如果是工程師，就用 GSC API 和 Python 將分析自動化吧。&lt;/p>
&lt;h3 id="31-gsc-api-與-python-的自動化方法">3.1 GSC API 與 Python 的自動化方法
&lt;/h3>&lt;p>建立一個腳本，自動偵測特定文章的搜尋排名是如何隨時間下降的（Decaying Content），或者顯示次數（曝光）很多但點閱率（CTR）卻異常低「很可惜的文章」。
這會使用到 &lt;code>google-api-python-client&lt;/code> 和 &lt;code>pandas&lt;/code>。&lt;/p>
&lt;h3 id="32-python-實作程式碼自動萃取-ctr-下降的內容">3.2 Python 實作程式碼：自動萃取 CTR 下降的內容
&lt;/h3>&lt;p>以下腳本範例是從 API 取得過去 30 天的搜尋成效數據，並萃取出顯示次數 1000 次以上且 CTR 在 2% 以下的「標題或描述有很大改善空間的關鍵字與文章 URL」。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">google.oauth2&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">service_account&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">googleapiclient.discovery&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">datetime&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. 認證與建立 API 服務&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">KEY_FILE_LOCATION&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;path/to/your-service-account-key.json&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">SCOPES&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;https://www.googleapis.com/auth/webmasters.readonly&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">SITE_URL&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;https://your-tech-blog.com/&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">credentials&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">service_account&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Credentials&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_service_account_file&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">KEY_FILE_LOCATION&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">scopes&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">SCOPES&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">webmasters_service&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">build&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;searchconsole&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;v1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">credentials&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">credentials&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. 計算請求期間（過去 30 天）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">today&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">date&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">today&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">end_date&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">today&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">timedelta&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">days&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">strftime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">start_date&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">today&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">timedelta&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">days&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">32&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">strftime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. 執行 API 請求&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">request&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;startDate&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">start_date&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;endDate&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;dimensions&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;query&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;rowLimit&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">5000&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">webmasters_service&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">searchanalytics&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">siteUrl&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">SITE_URL&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">body&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">request&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">execute&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. 使用 Pandas DataFrame 進行資料處理與過濾&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="s1">&amp;#39;rows&amp;#39;&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">rows&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;rows&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">row&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">rows&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Query&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;keys&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;URL&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;keys&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Clicks&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;clicks&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Impressions&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;impressions&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;CTR&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;ctr&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Position&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;position&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 過濾條件: 曝光次數 1000 以上 且 CTR 低於 2%&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">target_df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;Impressions&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="mi">1000&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;CTR&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mf">0.02&lt;/span>&lt;span class="p">)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 依照排名升冪排序（優先處理排名高卻沒有被點擊的項目）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">target_df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">target_df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sort_values&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">by&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;Position&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ascending&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【建議修改標題/Meta Description 的清單】&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">target_df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">head&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 根據需求輸出 CSV 等&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># target_df.to_csv(&amp;#39;improve_candidates.csv&amp;#39;, index=False)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;找不到數據。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>透過 cron 或 GitHub Actions 的定期任務來執行這個腳本，就能持續以數據驅動來決定「應該重寫哪篇文章的標題」。不依賴直覺，而是基於數據的持續改善（不是 CI/CD 而是 Continuous Content Improvement）是非常重要的。&lt;/p>
&lt;hr>
&lt;h2 id="4-文章的生命週期管理與重寫策略">4. 文章的生命週期管理與重寫策略
&lt;/h2>&lt;p>技術文章不是發布了就結束了。隨著技術的演進（框架的版號升級、API 的棄用等），內容很快就會過時。持續提供舊資訊不僅會損害部落格的信譽，在 SEO 上也會獲得負面評價。&lt;/p>
&lt;h3 id="41-內容生命週期管理甘特圖">4.1 內容・生命週期管理（甘特圖）
&lt;/h3>&lt;p>用 Mermaid 甘特圖來展示理想的內容營運生命週期。&lt;/p>
&lt;pre class="mermaid">
gantt
title 數據驅動型內容・生命週期管理
dateFormat YYYY-MM-DD
axisFormat %m/%d
section &amp;#34;階段1: 企劃・寫作&amp;#34;
&amp;#34;搜尋關鍵字・趨勢分析&amp;#34; :a1, 2026-09-01, 3d
&amp;#34;草稿・程式碼驗證&amp;#34; :a2, after a1, 5d
&amp;#34;推敲・校對&amp;#34; :a3, after a2, 2d
section &amp;#34;階段2: 發布・推廣&amp;#34;
&amp;#34;透過 CI/CD 管道進行部署&amp;#34; :p1, 2026-09-11, 1d
&amp;#34;自動 SNS 發布 (X, LinkedIn, RSS)&amp;#34; :p2, 2026-09-11, 1d
&amp;#34;擴散至社群書籤等&amp;#34; :p3, after p2, 3d
section &amp;#34;階段3: 觀測・分析&amp;#34;
&amp;#34;GSC 數據累積期間&amp;#34; :m1, 2026-09-14, 28d
&amp;#34;透過 Python API 進行成效評估&amp;#34;:m2, after m1, 2d
section &amp;#34;階段4: 改善 (重寫)&amp;#34;
&amp;#34;修改 CTR 下降文章的標題&amp;#34; :r1, after m2, 3d
&amp;#34;程式碼更新至最新版本&amp;#34;:r2, after r1, 4d
&lt;/pre>
&lt;p>像這樣，將文章撰寫視為一個軟體開發專案來對待，並將發布後的營運・維護（重寫）階段納入計畫，是維持與提升流量的秘訣。&lt;/p>
&lt;h3 id="42-內容創作的-roi投資回報率數學模型">4.2 內容創作的 ROI（投資回報率）數學模型
&lt;/h3>&lt;p>既然工程師要花費寶貴的時間寫文章，就應該意識到其投資回報率 (ROI)。
部落格的 ROI 可以公式化如下：&lt;/p>
$$ ROI = \frac{\sum_{t=1}^{T} \left( Rev_{ad}(t) + Val_{brand}(t) + Val_{skill}(t) \right) - Cost_{time}}{\text{Cost}_{time}} \times 100 \ (\%) $$&lt;ul>
&lt;li>$T$: 文章的有效壽命（直到過時的期間）&lt;/li>
&lt;li>$Rev_{ad}(t)$: 廣告收益、聯盟行銷收益、贊助等直接收益&lt;/li>
&lt;li>$Val_{brand}(t)$: 技術能力展示對職涯產生正面影響（轉職時錄取薪資增加、演講邀約等）的金錢換算值&lt;/li>
&lt;li>$Val_{skill}(t)$: 為了撰寫文章，自身進行學習與調查所帶來的自我技能提升價值&lt;/li>
&lt;li>$Cost_{time}$: 撰寫文章、製作圖解、驗證程式碼所花費的時間（換算成自己的時薪）&lt;/li>
&lt;/ul>
&lt;p>技術部落格最棒的一點是，即使 $Rev_{ad}$ 很少，$Val_{brand}$ 和 $Val_{skill}$ 也有變得極大的傾向。特別是高品質的技術解說會直接成為作品集，在轉職活動或獲取副業時發揮極大的威力。&lt;/p>
&lt;hr>
&lt;h2 id="5-結合-github-actions-與外部自動化工具的發布機制">5. 結合 GitHub Actions 與外部自動化工具的發布機制
&lt;/h2>&lt;p>建立內容後，如何有效率地傳遞給目標受眾（發布與分發）就成了一個課題。每次都手動將連結貼到各個 SNS 是沒有效率的，也不像工程師的作風。&lt;/p>
&lt;h3 id="51-社群媒體分享的自動化架構">5.1 社群媒體分享的自動化架構
&lt;/h3>&lt;p>建構一個架構，從將 Markdown 檔案合併到 GitHub 儲存庫的 main 分支那一刻起，到建置、部署、以及跨平台發布通知，都能完全自動化。&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;開發者 (Git Push)&amp;#34;] --&amp;gt; B[&amp;#34;GitHub 儲存庫&amp;#34;]
B --&amp;gt;|Webhook| C[&amp;#34;GitHub Actions (CI/CD)&amp;#34;]
C --&amp;gt;|Build| D[&amp;#34;靜態網站生成器 (Hugo/Gatsby)&amp;#34;]
D --&amp;gt;|Deploy| E[&amp;#34;主機代管 (Vercel / Cloudflare Pages)&amp;#34;]
D --&amp;gt;|Generate| F[&amp;#34;RSS Feed (index.xml)&amp;#34;]
F --&amp;gt;|Polled by| G[&amp;#34;Zapier / IFTTT / Make&amp;#34;]
G --&amp;gt;|API Call| H[&amp;#34;X (Twitter) 自動發文&amp;#34;]
G --&amp;gt;|API Call| I[&amp;#34;LinkedIn 文章發文&amp;#34;]
G --&amp;gt;|API Call| J[&amp;#34;Discord / Slack 社群 Webhook&amp;#34;]
C --&amp;gt;|Actions Script| K[&amp;#34;Qiita / Zenn 跨平台發布 API&amp;#34;]
&lt;/pre>
&lt;h3 id="52-自動化管道的建置重點">5.2 自動化管道的建置重點
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>透過 GitHub Actions 進行建置與部署&lt;/strong>
如果使用靜態網站生成器，可利用 GitHub Actions 將 HTML 的生成與部署到主機服務（Vercel, Netlify, Cloudflare Pages 等）自動化。這時，作為前述 Core Web Vitals 的對策，將圖片最佳化流程（例如自動轉換為 WebP）納入建置管道也是非常有效的。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>利用 Zapier/IFTTT 搭配 RSS 觸發的 SNS 串接&lt;/strong>
網站生成器在建置時會產生最新的 RSS feed (XML)。讓 Zapier 或 Make (前 Integromat) 等 iPaaS 讀取這個 feed，並建立「當 RSS 有新增項目時，就將標題和 URL 發布到 X (Twitter) 和 LinkedIn」的工作流程。這樣一來，文章發布的瞬間就能自動通知追蹤者。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>交叉發布 (Cross-Post) 到 Qiita/Zenn（Canonical 標籤的活用）&lt;/strong>
當自家部落格或個人部落格的網域權威（Domain Power）還很弱時，借用 Qiita 或 Zenn 等技術平台的集客力也是一種方法。但是，單純的複製貼上會有被當作重複內容而受到 SEO 懲罰的風險。
這個問題可以透過在 Qiita 或 Zenn 文章的 Meta Data 中設定 &lt;strong>Canonical 標籤&lt;/strong>，並指定自家部落格的原創文章 URL 來解決。透過 GitHub Actions 呼叫各種平台的 API，編寫從 Markdown 自動生成文章的腳本，就能完全自動化多管道的發布。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="結語轉動持續改善的循環">結語：轉動持續改善的循環
&lt;/h2>&lt;p>為了讓技術部落格的月流量出現戲劇性的成長，除了「寫作」這個行為之外，本次介紹的工程化方法也是不可或缺的。&lt;/p>
&lt;ol>
&lt;li>建立有意識到 SEO 的穩固 HTML 與網站架構&lt;/li>
&lt;li>規劃能理解使用者搜尋意圖（錯誤解決 vs 系統性學習）的文章&lt;/li>
&lt;li>充分運用 Google Search Console API 與 Python 進行數據分析&lt;/li>
&lt;li>意識到 ROI 的內容生命週期管理與重寫&lt;/li>
&lt;li>透過 CI/CD 與 Zapier 串接，實現發布的完全自動化&lt;/li>
&lt;/ol>
&lt;p>如果能將這些組合成一個系統，技術部落格將會成為強力推動你個人職涯的最強資產（Asset）。如果工程師正為了流量停滯而煩惱，請務必從今天開始嘗試「部落格的成長駭客」。在開發業務中培養出的程式設計技能與架構設計能力，在經營部落格時也一定會成為最強大的武器。&lt;/p></description></item><item><title>運用 Google Search Console 重新撰寫過往技術文章的策略</title><link>http://kenji.blog/zh-tw/p/google-search-console-rewrite-strategy/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/zh-tw/p/google-search-console-rewrite-strategy/</guid><description>&lt;img src="http://kenji.blog/p/google-search-console-rewrite-strategy/img/eyecatch.jpg" alt="Featured image of post 運用 Google Search Console 重新撰寫過往技術文章的策略" />&lt;h2 id="1-前言技術部落格中重新撰寫的重要性與數據驅動方法">1. 前言：技術部落格中重新撰寫的重要性與數據驅動方法
&lt;/h2>&lt;p>在經營技術部落格或針對開發者的自有媒體時，與持續撰寫新文章同等重要、甚至更重要的，就是「重新撰寫過往文章」。特別是 IT 與技術相關的主題，資訊過時得很快，幾年前寫的程式碼片段或 API 規格在現在已不建議使用 (Deprecated) 的情況也屢見不鮮。然而，如果只是盲目地更新舊文章，是無法將來自搜尋引擎的流量 (流入) 最大化的。&lt;/p>
&lt;p>因此，本文將解說如何活用 &lt;strong>Google Search Console (以下簡稱 GSC)&lt;/strong> 與 &lt;strong>Google Analytics 4 (GA4)&lt;/strong> 的數據，採用數據驅動且數學化的方法，來鎖定應該重新撰寫的技術文章，並大幅提升搜尋排名與點擊率 (CTR) 的進階策略。&lt;/p>
&lt;p>具體而言，我們將網羅各種方法，從運用 Python 和 BigQuery 整合 GSC 與 GA4 數據，找出相對於曝光次數但 CTR 卻很低的「錯失機會文章」，到使用 NLP (自然語言處理) 的 TF-IDF 分析，來找出 H2 或 H3 標題中缺乏的關鍵字，有效率地填補內容差距的手法。&lt;/p>
&lt;hr>
&lt;h2 id="2-預期-ctr-與實際-ctr-的差距分析-導入數學模型">2. 預期 CTR 與實際 CTR 的差距分析 (導入數學模型)
&lt;/h2>&lt;p>SEO 中最基本的指標之一就是「相對於搜尋排名的點擊率 (CTR)」。一般來說，當搜尋排名第 1 時的 CTR 大約是 25〜30%，第 2 名約 15%，之後便會呈現急遽下降的特性。這個排名與 CTR 的關係，可以被模型化為服從冪法則 (Power Law) 的分佈。&lt;/p>
&lt;p>已知相對於排名 $r$ 的預期點擊率 $CTR(r)$ 可以用以下數學公式來近似：&lt;/p>
$$
CTR(r) = a \cdot r^{-b}
$$&lt;p>在此，$a$ 代表第 1 名時的預期 CTR (例如：30% 的情況為 $0.30$)，$b$ 代表衰減參數 (通常介於 $1.0$ 到 $1.5$ 之間)。&lt;/p>
&lt;p>在選定要重新撰寫的文章時，最有效的方法是&lt;strong>找出「實際 CTR」遠低於「預期 CTR」的文章 (關鍵字)&lt;/strong>。舉例來說，儘管搜尋排名第 3 名 (預期 CTR 約為 10%)，但實際 CTR 卻只有 2% 的話，就可以判斷很有可能是搜尋意圖與標題、描述 (Description) 產生了落差，又或者是受到複合式摘要 (Rich Snippets) 等競爭因素的影響而被搶走了點擊。&lt;/p>
&lt;p>下方的圖表展示了某技術部落格中預期 CTR 與實際 CTR 之間落差的示意圖。&lt;/p>
&lt;pre class="mermaid">
xychart-beta
title 各排名的預期 CTR 與實際 CTR
x-axis [&amp;#34;1&amp;#34;, &amp;#34;2&amp;#34;, &amp;#34;3&amp;#34;, &amp;#34;4&amp;#34;, &amp;#34;5&amp;#34;, &amp;#34;6&amp;#34;, &amp;#34;7&amp;#34;, &amp;#34;8&amp;#34;, &amp;#34;9&amp;#34;, &amp;#34;10&amp;#34;]
y-axis &amp;#34;CTR (%)&amp;#34; 0 --&amp;gt; 35
line [30.5, 15.2, 10.1, 7.5, 5.2, 4.1, 3.2, 2.5, 2.0, 1.5]
bar [32.1, 14.0, 8.5, 4.0, 5.0, 2.1, 1.5, 1.0, 1.2, 0.5]
&lt;/pre>
&lt;p>(※ 折線代表預期 CTR，長條圖代表實際 CTR。可以確認在第 4 名與第 8 名時出現了大幅低於預期的情況。)&lt;/p>
&lt;hr>
&lt;h2 id="3-使用-gsc-api-自動擷取搜尋成效數據-python">3. 使用 GSC API 自動擷取搜尋成效數據 (Python)
&lt;/h2>&lt;p>雖然從 GSC 的網頁介面下載 CSV 進行分析也是可行的，但為了應付大規模的部落格或進行持續性的分析，最好的方式還是建構一套使用 GSC API 搭配 Python 來自動擷取數據的機制。&lt;/p>
&lt;p>以下展示了一個 Python 程式碼片段，使用 &lt;code>google-api-python-client&lt;/code> 來取得特定期間內依頁面、依查詢 (Query) 的成效數據 (點擊次數、曝光次數、CTR、平均排名)。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">google.oauth2&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">service_account&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">googleapiclient.discovery&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">get_gsc_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">key_path&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">site_url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">start_date&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 讀取認證資訊並建構 API 客戶端&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">credentials&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">service_account&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Credentials&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_service_account_file&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">key_path&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">scopes&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;https://www.googleapis.com/auth/webmasters.readonly&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">service&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">build&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;searchconsole&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;v1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">credentials&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">credentials&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># API 請求的 Payload 設定 (指定頁面與查詢為維度)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">request&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;startDate&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">start_date&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;endDate&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;dimensions&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;query&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;rowLimit&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">25000&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 執行 API&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">service&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">searchanalytics&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">siteUrl&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">site_url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">body&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">request&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">execute&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 從回應中擷取數據並轉換為 Pandas DataFrame&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">rows&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;rows&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">row&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">rows&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">keys&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;keys&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">keys&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;query&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">keys&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;clicks&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;clicks&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;impressions&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;impressions&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;ctr&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;ctr&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;position&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;position&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 執行範例&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># df_gsc = get_gsc_data(&amp;#39;credentials.json&amp;#39;, &amp;#39;https://kenji.blog/&amp;#39;, &amp;#39;2026-08-01&amp;#39;, &amp;#39;2026-08-31&amp;#39;)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># print(df_gsc.head())&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>透過這支腳本，可以將頁面 URL 與搜尋查詢關聯起來，以 DataFrame 的形式取得詳細數據。這使得我們能夠全面掌握特定文章是透過哪些關鍵字顯示出來的。&lt;/p>
&lt;hr>
&lt;h2 id="4-使用正規表示式-regex-過濾技術關鍵字">4. 使用正規表示式 (Regex) 過濾技術關鍵字
&lt;/h2>&lt;p>在技術部落格的分析中，GSC 的&lt;strong>正規表示式 (Regex) 過濾器&lt;/strong>是一項非常強大的功能。
舉例來說，當撰寫的文章橫跨前端、後端到基礎設施等多種領域時，我們有時會希望只萃取出「與 Python 或 Pandas 相關的錯誤或教學文章」，藉此決定重新撰寫的優先順序。&lt;/p>
&lt;p>使用 GSC 的自訂正規表示式過濾器，就可以透過複雜的條件來篩選查詢。&lt;/p>
&lt;p>&lt;strong>技術關鍵字過濾的實際範例:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Python 相關的錯誤調查: &lt;code>^(python|pandas|numpy|matplotlib).* (error|exception|bug|錯誤|無法執行)&lt;/code>&lt;/li>
&lt;li>AWS 相關的基礎設施建置: &lt;code>(aws|amazon web services|ec2|s3|lambda).* (建置|設定|教學|tutorial|how to)&lt;/code>&lt;/li>
&lt;li>特定函式庫的版本升級: &lt;code>(react|vue|angular) (v17|v18|v3) (migration|遷移|轉移)&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>若要將此整合到 GSC API 的請求中，可以活用 &lt;code>dimensionFilterGroups&lt;/code> 來加上正規表示式的條件。充分利用這種過濾方式，就能精準地萃取出開發者「正因為遇到困難而進行搜尋」的高價值、解決問題型關鍵字。&lt;/p>
&lt;hr>
&lt;h2 id="5-透過-bigquerypandas-整合-ga4-與-gsc-數據">5. 透過 BigQuery/Pandas 整合 GA4 與 GSC 數據
&lt;/h2>&lt;p>只靠 GSC 的數據，我們只能知道「搜尋排名與點擊率」。若要了解「來到該文章的使用者，實際停留了多久，以及是否達成轉換 (例如：前往 GitHub 儲存庫或訂閱電子報等)」，就必須整合 (JOIN) &lt;strong>Google Analytics 4 (GA4)&lt;/strong> 的數據。&lt;/p>
&lt;p>如果已將 GA4 的匯出數據與 GSC 的批次匯出數據儲存在 BigQuery 中，可以透過以下 SQL 查詢將兩者結合，進而萃取出「曝光次數多、搜尋排名也還不錯，但跳出率高或參與時間短的文章」。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">WITH&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">gsc_data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SUM&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">impressions&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SUM&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">clicks&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">total_clicks&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">AVG&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sum_top_position&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">avg_position&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="o">`&lt;/span>&lt;span class="n">project&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">searchconsole&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">searchdata_url_impression&lt;/span>&lt;span class="o">`&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">data_date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BETWEEN&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;2026-08-01&amp;#39;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;2026-08-31&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">GROUP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">ga4_data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">REGEXP_REPLACE&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">string_value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">UNNEST&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">event_params&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">key&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;page_location&amp;#39;&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="s1">&amp;#39;^https?://[^/]+&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">COUNT&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">DISTINCT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">user_pseudo_id&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">users&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">AVG&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">int_value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">UNNEST&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">event_params&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">key&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;engagement_time_msec&amp;#39;&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1000&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">avg_engagement_sec&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="o">`&lt;/span>&lt;span class="n">project&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">analytics_123456789&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">events_&lt;/span>&lt;span class="o">*`&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">event_name&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;page_view&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">GROUP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_clicks&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">SAFE_DIVIDE&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_clicks&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">ctr&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">avg_position&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">users&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">avg_engagement_sec&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">gsc_data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">JOIN&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">ga4_data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ON&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1000&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">avg_position&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BETWEEN&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">15&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">ORDER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">DESC&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>利用這個結果，我們可以依照以下矩陣將要重新撰寫的對象進行分類：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>High Impression, Low CTR, High Engagement&lt;/strong>:
只要在搜尋結果中被點擊，讀者就會感到滿意的文章。應將&lt;strong>修改標題與 Meta Description&lt;/strong> 列為最優先事項。&lt;/li>
&lt;li>&lt;strong>High CTR, Low Engagement&lt;/strong>:
雖然會被點擊，但內容不如預期而導致讀者離開的文章。需要進行大規模的內文重新撰寫，例如&lt;strong>改善前言、更新至最新的程式碼，以及提升資訊的完整度 (新增 H2/H3)&lt;/strong>。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="6-使用-nlp-與-tf-idf-進行內容差距分析">6. 使用 NLP 與 TF-IDF 進行內容差距分析
&lt;/h2>&lt;p>鎖定應該重新撰寫的文章後，接下來要做的就是分析「具體來說應該新增什麼樣的標題 (H2/H3) 或關鍵字」。在這裡我們同樣不依靠直覺，而是活用&lt;strong>自然語言處理 (NLP) 中的 TF-IDF (Term Frequency-Inverse Document Frequency)&lt;/strong>。&lt;/p>
&lt;p>TF-IDF 是一種用來評估某個單字在該文件中重要程度的統計量。&lt;/p>
$$
TF\text{-}IDF(t, d) = tf(t, d) \times \log\left(\frac{N}{df(t)}\right)
$$&lt;p>在此，&lt;/p>
&lt;ul>
&lt;li>$tf(t, d)$ 為單字 $t$ 在文件 $d$ 中的出現頻率&lt;/li>
&lt;li>$N$ 為所有文件的總數&lt;/li>
&lt;li>$df(t)$ 為出現單字 $t$ 的文件數量&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>方法:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>透過網路爬蟲等方式，取得目標關鍵字排名前 10 名的文章 (競爭對手網站) 的文字數據。&lt;/li>
&lt;li>準備好自己網站中目標文章的文字數據。&lt;/li>
&lt;li>使用 Python &lt;code>scikit-learn&lt;/code> 的 &lt;code>TfidfVectorizer&lt;/code>，萃取出在競爭對手前幾名文章中普遍獲得高分，但在自己網站的文章中卻不存在，或是分數明顯偏低的關鍵字 (特徵詞)。&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">sklearn.feature_extraction.text&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">TfidfVectorizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># documents = [自己網站的文字, 競爭對手文章1的文字, 競爭對手文章2的文字, ...]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 這裡假設已經備妥使用中文斷詞系統 (如 Jieba 等) 切分好的文字列表&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">extract_missing_keywords&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">documents&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vectorizer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">TfidfVectorizer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">max_df&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.9&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">min_df&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tfidf_matrix&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">vectorizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fit_transform&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">documents&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">feature_names&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">vectorizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_feature_names_out&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 計算競爭對手文章 (索引 1 之後) 的平均 TF-IDF 分數&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">competitor_mean_tfidf&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mean&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">tfidf_matrix&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">:]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">toarray&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">axis&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 取得自己網站文章 (索引 0) 的 TF-IDF 分數&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">my_article_tfidf&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">tfidf_matrix&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">toarray&lt;/span>&lt;span class="p">()[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 計算競爭對手覺得重要，但自己網站中缺乏 (或較少) 的單字差距&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">gap_scores&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">competitor_mean_tfidf&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">my_article_tfidf&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 萃取出差距最大的前幾名單字&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df_gap&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s1">&amp;#39;keyword&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">feature_names&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;gap_score&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">gap_scores&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df_gap&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df_gap&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sort_values&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">by&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;gap_score&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ascending&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">df_gap&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">head&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">20&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 範例: missing_keywords = extract_missing_keywords(processed_docs)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># print(missing_keywords)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>透過這項分析，可以量化地發現&lt;strong>主題的遺漏 (內容差距)&lt;/strong>，例如：「原來排名前面的文章也提到了『部署至 Docker 容器的方法』與『建置 CI/CD 流程』，但我的文章卻沒有觸及」。&lt;/p>
&lt;p>發現的重要關鍵字群不能只是隨便散佈在內文中，而是必須將它們作為有意義的段落，以 &lt;strong>H2 或 H3 標題 (Heading 標籤)&lt;/strong> 的形式加入，並針對標題撰寫詳細的技術解說與程式碼片段，如此一來便能大幅提升 Google 的評價。&lt;/p>
&lt;hr>
&lt;h2 id="7-數據管道與持續改善循環">7. 數據管道與持續改善循環
&lt;/h2>&lt;p>上述解說的流程並不是做一次就結束了，將其管道化 (Pipeline) 並持續執行，才是 SEO 成功的關鍵。以下使用 Mermaid 的流程圖來展示整體的架構與營運流程。&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;GSC API 數據 (曝光次數, 點擊次數, 排名)&amp;#34;] --&amp;gt; C[&amp;#34;BigQuery / 數據倉儲&amp;#34;]
B[&amp;#34;GA4 匯出數據 (頁面瀏覽量, 參與時間)&amp;#34;] --&amp;gt; C
C --&amp;gt; D[&amp;#34;Python / Pandas 數據整合與分析&amp;#34;]
D --&amp;gt; E[&amp;#34;鎖定高曝光 / 低 CTR 的文章&amp;#34;]
E --&amp;gt; F[&amp;#34;NLP 競爭對手爬蟲與 TF-IDF 關鍵字萃取&amp;#34;]
F --&amp;gt; G[&amp;#34;最佳化 H2/H3 標籤與重新撰寫內容&amp;#34;]
G --&amp;gt; H[&amp;#34;發布更新後的文章&amp;#34;]
H --&amp;gt; I[&amp;#34;監控 CTR 變化 (預期與實際比較)&amp;#34;]
I --&amp;gt; |&amp;#34;回饋循環&amp;#34;| A
&lt;/pre>
&lt;p>像這樣，將從 GSC 與 GA4 收集數據、透過分析選定目標、利用 NLP 最佳化內容，一直到監控結果的一連串流程系統化，就能讓部落格媒體成為持續自動成長的資產。&lt;/p>
&lt;hr>
&lt;h2 id="8-總結與未來展望">8. 總結與未來展望
&lt;/h2>&lt;p>活用 Google Search Console 來重新撰寫技術文章，並不僅僅是修改文字而已。這是一項針對搜尋引擎演算法這個黑盒子，透過運用數據與數學模型來提出最佳解答的高階工程。&lt;/p>
&lt;p>總結本文解說的手法：&lt;/p>
&lt;ol>
&lt;li>計算&lt;strong>預期 CTR 與實際 CTR 的落差&lt;/strong>，鎖定修改後成效最顯著的文章。&lt;/li>
&lt;li>使用 &lt;strong>GSC API 與 Python&lt;/strong> 自動擷取成效數據。&lt;/li>
&lt;li>在 &lt;strong>BigQuery&lt;/strong> 上結合 GA4 的參與度數據，修改跳出率較高文章的內文。&lt;/li>
&lt;li>透過&lt;strong>使用 TF-IDF 的 NLP 分析&lt;/strong>，發現與競爭對手之間的內容差距，並最佳化標題 (H2/H3)。&lt;/li>
&lt;/ol>
&lt;p>技術趨勢會不斷改變。為了能精準回應讀者目前面臨的錯誤或課題，請務必將這種數據為輔的戰略性重新撰寫，融入到日常的營運當中。&lt;/p></description></item></channel></rss>