(Jul 30, 2026)
香港人在網上表達 Burnout 時,極少直接使用「職業倦怠」等書面語。你必須將關鍵字庫分為「核心詞」、「本土口語」及「病徵/行為詞」,並使用 AND / OR 邏輯進行組合。
通用的大型社交媒體(如 Instagram 牆面、Facebook 公開專頁) 通常只能抓到官方或 KOL 的心靈雞湯。真正的 Burnout 數據隱藏在以下高匿名性的本地平台: [1, 5]
【主要渠道】
├── LIHKG(連登討論區) ─── 打工仔最真實、最赤裸的 Burnout 圍爐區(如:上班台、職場板)
├── Facebook 匿名專頁 ─── 針對特定行業的樹洞(如:Secrets 系列專頁、HKDSE/大學 Secrets)
├── Threads ─────── 近年新興的情緒宣洩地,多以第一人稱書寫「返工日常的崩潰」
└── 香港本地論壇 ───── 香港討論區(Discuss)、Uwants 的「職場交流」版塊
許多歐美主流工具(如 Brandwatch, Hootsuite)對廣東話口語(如「攰」、「唔想」)的語意分析及情感判定(Sentiment Analysis)極不準確。在香港做這項研究,強烈建議優先考慮大中華區或本地開發的系統: [6, 7]
抓取到數據後,不應只看「聲量(Volume)」,必須透過標籤(Tagging)將數據切細,抽出有價值的 Insight: [7, 13]
如果想讓這個 Social Listening 項目更落地,您可以告訴我:
我可以為您規劃更具體的關鍵字布林邏輯(Boolean Logic)公式或報告架構。
利用 Vibe Coding 工具,您不需要精通編程,只需用自然語言(Prompt)命令 AI 幫您寫出專門抓取香港網頁數據的腳本(Script)。
"請幫我用 Python 寫一個簡單的網頁爬蟲。目標是抓取 Google 搜尋結果中有關香港地區、包含關鍵字「爆煲」或「Burnout」的公開討論區(如連登 LIHKG、香港討論區)網頁標題和內文摘要。請使用 BeautifulSoup 和 Requests 庫,並加上時間限制(例如過去一個月),結果匯出為 CSV 檔。"
由於 Twitter(X) 和 Reddit 的 API 開始收費,針對香港本土研究,您可以利用以下免費渠道:
拿到一堆廣東話的留言 CSV 檔後,您不需要買昂貴的語意分析系統,可以用以下免費工具處理:
如果您準備開始用 Vibe Coding 工具動手做,您可以告訴我:
我可以為您直接寫出第一版免費用於抓取數據的 Python 程式碼藍本,讓您直接複製去執行!
不同的渠道有不同的「免費抓取」應對方法,您的 Vibe Code 程式碼會分為四個模組:
<td> 標籤,只要標題包含關鍵字,就點進去把內文抓下來。當上述四個渠道的數據被抓下來後,會進入一個名為 data_pipeline.py 的免費本地腳本:
這是 Vibe Coding 架構最強大的地方。您不需要自己寫繁複的廣東話自然語言處理(NLP)程式碼,而是直接呼叫免費的 AI API 或手動導出導入。
[主要渠道 (連登/Threads/FB)]
│
▼ (Python 腳本定時執行/手動觸發)
[本地 CSV / Google Sheets 數據庫]
│
▼ (打包留言,發送給 AI)
[免費 AI (如 Claude / ChatGPT)] ─── 進行廣東話翻譯、情感分類 (正面/負面/爆煲)
│
▼
[Orange Data Mining / Excel] ─── 生成免費的數據圖表 (例如:Sunday Blue 關鍵字趨勢)
當您把這個架構搭建好後,您的日常監控動作其實非常簡單:
您想先看看負責抓取連登(LIHKG)或Threads的 Python 程式碼藍本嗎?我可以為您寫出一段您可以直接放入 Cursor 執行的原始碼。
我們必須使用 Playwright(微軟開源的自動化庫)。它的原理是直接啟動一個真實的 Chromium 瀏覽器,模擬人類的滑鼠滾動、隨機延遲和點擊,這樣防爬蟲系統就會認為你是真實的香港打工仔,而不是機械人。 請在 Cursor 中創建一個名為 hk_burnout_monitor.py 的檔案,並將以下完整程式碼複製進去:
pip install playwright pandas playwright install chromium
hk_burnout_monitor.py)import asyncio
import random
import time
import pandas as pd
from playwright.async_api import async_playwright
# 1. 反爬蟲核心配置:模擬真實人類行為的延遲函數
async def human_delay(min_sec=2, max_sec=5):
"""隨機等待,防止被識別為機械人"""
await asyncio.sleep(random.uniform(min_sec, max_sec))
# 2. 連登 (LIHKG) 抓取模組
async def scrape_lihkg(page, keyword):
print(f"🕵️ 正在搜尋連登關鍵字: {keyword}...")
search_url = f"https://lihkg.com{keyword}"
# 模擬真實瀏覽器 Profile
await page.goto(search_url, wait_until="networkidle")
await human_delay(3, 6)
posts = []
# 抓取搜尋結果中的帖子列表
# 連登的帖子標題通常在特定 class 內,這裡使用 CSS Selector 抓取
selectors = await page.query_selector_all('div[class*="_28Y0m"]')
# 如果 class 改變,退一步抓取所有含有標題連結的 A 標籤
if not selectors:
selectors = await page.query_selector_all('a[href^="/thread/"]')
for selector in selectors[:15]: # 每次只抓前 15 條,避免動作太大被封
try:
title = await selector.inner_text()
url = await selector.get_attribute("href")
full_url = f"https://lihkg.com{url}" if url and not url.startswith("http") else url
if title and any(k in title for k in [keyword, "返工", "攰", "放工"]):
posts.append({
"Platform": "LIHKG",
"Keyword": keyword,
"Title/Content": title.strip().replace("\n", " "),
"URL": full_url,
"Timestamp": time.strftime("%Y-%m-%d")
})
except Exception as e:
continue
return posts
# 3. Threads 抓取模組
async def scrape_threads(page, keyword):
print(f"🕵️ 正在搜尋 Threads 關鍵字: {keyword}...")
search_url = f"https://threads.net{keyword}"
await page.goto(search_url, wait_until="networkidle")
await human_delay(4, 7)
# Threads 需要向下滾動才能加載更多動態內容
for _ in range(3):
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await human_delay(1.5, 3)
posts = []
# Threads 的文字內容通常存在於具有特定屬性的 span 或 div 中
selectors = await page.query_selector_all('span')
for selector in selectors:
try:
text = await selector.inner_text()
# 過濾長度太短的字,或不相關的按鈕文字(如:回覆、讚)
if len(text) > 15 and keyword in text:
posts.append({
"Platform": "Threads",
"Keyword": keyword,
"Title/Content": text.strip().replace("\n", " "),
"URL": search_url,
"Timestamp": time.strftime("%Y-%m-%d")
})
except Exception:
continue
# 去除 Threads 重複抓取的文字片段
seen = set()
unique_posts = []
for p in posts:
if p["Title/Content"] not in seen:
seen.add(p["Title/Content"])
unique_posts.append(p)
return unique_posts[:15]
# 4. 主程序:控制瀏覽器生命週期
async def main():
# 香港打工仔最常用的 Burnout 本土關鍵字庫
keywords = ["爆煲", "頂唔順", "裸辭"]
all_results = []
async with async_playwright() as p:
# Launch 參數非常關鍵:headless=False 可以讓你親眼看著瀏覽器跑,避開反爬
# chromium.launch_persistent_context 可以儲存 Cookies,越跑越像真人
browser = await p.chromium.launch(
headless=False,
args=["--disable-blink-features=AutomationControlled"] # 隱藏機械人特徵
)
page = await browser.new_page()
# 設定偽裝成真實香港 Windows 用戶的 User-Agent
await page.set_extra_http_headers({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept-Language": "zh-HK,zh;q=0.9,en-US;q=0.8,en;q=0.7"
})
for kw in keywords:
# 抓取連登
lihkg_data = await scrape_lihkg(page, kw)
all_results.extend(lihkg_data)
await human_delay(5, 10) # 轉換關鍵字之間,休息久一點
# 抓取 Threads
threads_data = await scrape_threads(page, kw)
all_results.extend(threads_data)
await human_delay(5, 10)
await browser.close()
# 5. 導出數據成公益研究用的 CSV
if all_results:
df = pd.DataFrame(all_results)
# 去除完全重複的行
df.drop_duplicates(subset=["Title/Content"], inplace=True)
output_file = f"hk_burnout_listening_{time.strftime('%Y%m%d')}.csv"
df.to_csv(output_file, index=False, encoding="utf-8-sig") # utf-8-sig 確保 Excel 打開廣東話不亂碼
print(f"📊 報告生成成功!已儲存至: {output_file} (共 {len(df)} 條有機數據)")
else:
print("❌ 未能抓取到數據,請檢查網站結構是否改變。")
if __name__ == "__main__":
asyncio.run(main())
human_delay):每次點擊或加載都隨機等待 3-7 秒。絕對不要使用固定的 time.sleep(1),那是非常明顯的機械人特徵。接下來,您可以在 Cursor 的 Terminal 輸入 python hk_burnout_monitor.py 測試一下。 執行成功後,您會得到一個 CSV 檔案。想知道拿到這個 CSV 檔案後,如何用免費的 AI (如 Claude/ChatGPT) 進行精準的「廣東話情緒指標」批量分析嗎?
以下是為你修改後的完整 Cursor 程式碼。它會自動讀取外部的 keywords.csv,隨機抽取 N 個執行,並會溫馨提示你今天測試了哪些詞。
你可以直接在 Cursor 中新建一個名為 keywords.csv 的檔案,或者用 Excel 寫好後儲存為 CSV(格式如下,只需一列,頂部一定要有 keyword 這個 Header):
keyword
爆煲
頂唔順
裸辭
返工返到抑鬱
個人好頹
星期日焦慮
射波
奴工
想死
炒老闆魷魚
請將原來的程式碼全部替換為以下優化版。程式碼中加入了隨機抽樣邏輯(random.sample),並設定了 N_KEYWORDS 變數供你自由調整。
import asyncio
import random
import time
import os
import pandas as pd
from playwright.async_api import async_playwright
# === 參數設定 ===
CSV_KEYWORDS_FILE = "keywords.csv" # 外部關鍵字檔案名稱
N_KEYWORDS = 3 # 每次執行隨機抽取的關鍵字數量 (N)
# 1. 反爬蟲核心配置:模擬真實人類行為的延遲函數
async def human_delay(min_sec=2, max_sec=5):
await asyncio.sleep(random.uniform(min_sec, max_sec))
# 2. 連登 (LIHKG) 抓取模組
async def scrape_lihkg(page, keyword):
print(f"🕵️ [LIHKG] 正在搜尋: {keyword}...")
search_url = f"https://lihkg.com{keyword}"
try:
await page.goto(search_url, wait_until="networkidle")
await human_delay(3, 6)
posts = []
selectors = await page.query_selector_all('a[href^="/thread/"]')
if not selectors:
selectors = await page.query_selector_all('div[class*="_28Y0m"]')
for selector in selectors[:15]:
try:
title = await selector.inner_text()
url = await selector.get_attribute("href")
full_url = f"https://lihkg.com{url}" if url and not url.startswith("http") else url
if title:
posts.append({
"Platform": "LIHKG",
"Keyword": keyword,
"Title/Content": title.strip().replace("\n", " "),
"URL": full_url,
"Timestamp": time.strftime("%Y-%m-%d")
})
except Exception:
continue
return posts
except Exception as e:
print(f"⚠️ 連登抓取超時或失敗: {e}")
return []
# 3. Threads 抓取模組
async def scrape_threads(page, keyword):
print(f"🕵️ [Threads] 正在搜尋: {keyword}...")
search_url = f"https://threads.net{keyword}"
try:
await page.goto(search_url, wait_until="networkidle")
await human_delay(4, 7)
for _ in range(3):
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await human_delay(1.5, 3)
posts = []
selectors = await page.query_selector_all('span')
for selector in selectors:
try:
text = await selector.inner_text()
if len(text) > 15: # 簡化過濾,後續靠 AI 篩選
posts.append({
"Platform": "Threads",
"Keyword": keyword,
"Title/Content": text.strip().replace("\n", " "),
"URL": search_url,
"Timestamp": time.strftime("%Y-%m-%d")
})
except Exception:
continue
seen = set()
unique_posts = []
for p in posts:
if p["Title/Content"] not in seen:
seen.add(p["Title/Content"])
unique_posts.append(p)
return unique_posts[:15]
except Exception as e:
print(f"⚠️ Threads 抓取超時或失敗: {e}")
return []
# 4. 主程序:自動讀取外部 CSV 並隨機抽樣
async def main():
# 檢查外部 CSV 是否存在
if not os.path.exists(CSV_KEYWORDS_FILE):
print(f"❌ 錯誤:找不到外部關鍵字檔案 '{CSV_KEYWORDS_FILE}',請先建立該檔案。")
return
try:
# 讀取 CSV 中的關鍵字
df_keywords = pd.read_csv(CSV_KEYWORDS_FILE, encoding="utf-8-sig")
all_keywords_list = df_keywords['keyword'].dropna().astype(str).tolist()
all_keywords_list = [k.strip() for k in all_keywords_list if k.strip()]
except Exception as e:
print(f"❌ 讀取 CSV 檔案失敗,請檢查 Header 是否為 'keyword'。錯誤原因: {e}")
return
if not all_keywords_list:
print("❌ 關鍵字列表為空,請在 CSV 中加入關鍵字。")
return
# 自動計算 N 的有效值,防止 N 大於關鍵字總數
actual_n = min(N_KEYWORDS, len(all_keywords_list))
# 🌟 核心邏輯:隨機抽取任意 N 個關鍵字
selected_keywords = random.sample(all_keywords_list, actual_n)
print(f"🎯 關鍵字總數: {len(all_keywords_list)} 個。本次隨機抽取 {actual_n} 個執行監控。")
print(f"📋 今日監控詞清單: {selected_keywords}\n")
all_results = []
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
args=["--disable-blink-features=AutomationControlled"]
)
page = await browser.new_page()
await page.set_extra_http_headers({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept-Language": "zh-HK,zh;q=0.9,en-US;q=0.8,en;q=0.7"
})
for kw in selected_keywords:
# 抓取連登
lihkg_data = await scrape_lihkg(page, kw)
all_results.extend(lihkg_data)
await human_delay(5, 12)
# 抓取 Threads
threads_data = await scrape_threads(page, kw)
all_results.extend(threads_data)
await human_delay(5, 12)
await browser.close()
# 5. 導出結果
if all_results:
df_output = pd.DataFrame(all_results)
df_output.drop_duplicates(subset=["Title/Content"], inplace=True)
output_file = f"hk_burnout_listening_{time.strftime('%Y%m%d')}.csv"
# 如果當天多次執行,自動追加(Append)而不是覆蓋,方便累積數據
if os.path.exists(output_file):
df_existing = pd.read_csv(output_file, encoding="utf-8-sig")
df_combined = pd.concat([df_existing, df_output], ignore_index=True)
df_combined.drop_duplicates(subset=["Title/Content"], inplace=True)
df_combined.to_csv(output_file, index=False, encoding="utf-8-sig")
print(f"\n📊 數據已追加!總共累積: {len(df_combined)} 條有機數據 ──> {output_file}")
else:
df_output.to_csv(output_file, index=False, encoding="utf-8-sig")
print(f"\n📊 新報告生成成功!已儲存至: {output_file} (共 {len(df_output)} 條數據)")
else:
print("\n❌ 本次抽取未抓取到有效新數據。")
if __name__ == "__main__":
asyncio.run(main())
N_KEYWORDS = 3。例如你想每次只低調跑 1 個,就改成 1;想跑 5 個就改成 5。hk_burnout_listening_2026xxxx.csv 檔案內,不會互相覆蓋!現在你可以在 keywords.csv 裡塞滿你需要的香港口語,然後在 Cursor Terminal 輸入 python hk_burnout_monitor.py 測試一下。 當你有了這個自動收集的 CSV 檔案,下一步你想了解如何將抓取到的這幾百行廣東話「無痛、免費」地交給大型 AI 進行主題分類與情感標籤嗎?
雖然 AI 支援上傳 CSV,但有時因為 Excel 的編碼問題,廣東話可能出現亂碼。最穩妥的做法是:
hk_burnout_listening_xxxx.csv。打開免費版的 Claude 3.5 Sonnet 或 ChatGPT,將你的 comments.txt 拖進對話框,或者直接將文字貼進去,並在頂部或底部附上以下這段專門調教過的「廣東話 Burnout 分析器」提示詞:
你是一位精通香港職場文化與心理健康的社會科學專家。
請分析附件中從香港討論區/Threads抓取的打工仔廣東話留言,完成以下公益研究分析任務:
1. 【整體情緒溫度計】
請統計並將所有留言分類為以下四種 Burnout 嚴重程度,並給出百分比估算及核心原因簡述:
- 輕度焦慮(返工攰、日常抱怨)
- 中度爆煲(明顯對管理層憤怒、長期失眠、星期日焦慮)
- 重度耗竭(有實質行動:準備裸辭、射波、尋求輔導)
- 急需援助(文字透露極度絕望、有自殘或放棄生命傾向 —— *註:此項如發現請特別標出*)
2. 【三大 Burnout 核心源頭】
根據留言文本,歸納出導致香港打工仔 Burnout 的前三大核心原因(例如:長工時、有毒管理、薪酬與付出不成正比等),並為每項原因提供 2-3 句具體的廣東話留言作為佐證(Quote)。
3. 【香港本土 Burnout 行為詞典】
請列出文本中網民用來表達 Burnout 的最頻繁香港口語/流行語(例如:射波、SL、頹、爆煲),並解釋他們在使用這些詞時背後的真實心理狀態。
請以結構清晰的 Markdown 格式、繁體中文(香港地區習慣用語)輸出這份公益研究分析簡報。
如果你不想每次手動複製貼上,且擁有免費的 AI API Key(例如 Gemini Flash 的免費額度,或本地運行的 Ollama + Llama3),你可以讓 Cursor 幫你寫一個 analyze_burnout.py。
"請幫我寫一個 Python 腳本。它會讀取 hk_burnout_listening_xxxx.csv 中的 Title/Content 欄位,將所有文本打包,並呼叫 API(例如免費的 Google Gemini API 或是 OpenAI 相容的本地 API),將我提供的 Prompt(貼上方的 Markdown Prompt)發送出去,最後將 AI 生成的分析報告自動儲存為一個 burnout_report_xxxx.md 的文字檔。"
如果想讓你的公益研究報告更有說服力,接下來我們可以:
你希望朝哪個方向繼續深化這個項目?