iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0
AI 自動化

用 LINE Bot 和 Agent Skill 自動化整理筆記與 IG 發文系列 第 13 篇

Day 13|抓不到內文的網站:只憑網址和備註也要存得進去

  • 分享至 

  • xImage
  •  

昨天講完三層 fallback 怎麼保住 AI 分類這一步,今天往前一步,看抓網頁內文那一關會遇到什麼狀況。Facebook、Instagram、Threads 這種平台,本來就會擋外部爬蟲,Jina Reader 也一樣抓不動。這時候整套流程該怎麼辦?

先看 fetchReadable 這支函式:

async function fetchReadable(url, env) {
  const headers = { 'User-Agent': 'line-notion-bot' };
  if (env.JINA_API_KEY) {
    headers['Authorization'] = `Bearer ${env.JINA_API_KEY}`;
  }

  const res = await fetch(`https://r.jina.ai/${url}`, { headers });

  if (!res.ok) throw new Error(`無法讀取網頁(${res.status})`);

  const text = await res.text();
  return text.slice(0, MAX_CONTENT_CHARS);
}

碰到會擋爬蟲的網站,Jina Reader 那邊回來的不會是 200,fetchReadable 就直接 throw 出去,不吃這個錯誤。真正決定「要不要讓整個流程死掉」的,是呼叫端 handleTextMessage 裡包的那層 try/catch:

try {
  let content = '';
  try {
    content = await fetchReadable(url, env);
  } catch (fetchErr) {
    // Facebook / Instagram / Threads 等平台常擋爬蟲,抓不到內文時退化成只憑網址與備註分類,
    // 不整段失敗,讓筆記至少能被存下來。
    content = '(此網頁無法自動讀取內文,可能為需要登入的社群平台)';
  }
  const existingTags = await getExistingTags(env);
  const result = await classify(env, { url, content, userNote, existingTags });
  const saved = await createNotionPage(env, { ...result, url });
  ...
} catch (err) {
  await reply(env, replyToken, `⚠️ 處理失敗:${err.message}\n原始連結已保留:${url}`);
}

注意這裡是兩層 try/catch 疊在一起,不是只有一層。外層那個是整個存筆記流程的最後防線,真的整段掛掉時,至少把原始連結印在回覆裡,讓我自己複製貼上手動處理。內層這個才是今天的重點:專門包住 fetchReadable 這一步,抓不到內文的話,不會讓例外往外拋、觸發外層的「處理失敗」,而是把 content 換成一句固定的說明文字,讓流程繼續往下走。

換句話說,抓不到內文對整條流程來說不是「失敗」,只是「這篇少一項資料」。classify 照樣會拿到 url、這句佔位文字、userNote、還有既有標籤,餵給 AI 去分類。AI 沒有內文可讀,但網址本身(例如網域是 facebook.com)加上我自己順手打的備註,通常還是能猜出個大概分類,標籤跟摘要品質會差一點,但至少這篇筆記進得了 Notion,不會整個消失在對話紀錄裡。

這個取捨背後的邏輯很單純:比起「這篇分類得不夠精準」,「這篇根本沒存到」才是真正的損失。分類下得不準,我還可以事後貼連結回去改分類、加註記;但如果因為抓不到內文就讓整個請求直接失敗,連進 Notion 的機會都沒有,這篇連結八成就這樣被我滑過去、再也找不回來了。所以這裡選的是「先求有、再求好」,把降級的門檻卡在抓內文這一步就好,不要往上蔓延到整個存筆記的流程。

也因為這樣,fetchReadable 本身完全不用處理「抓不到內文怎麼辦」這種邊界情況,它只要老實回報「這次抓失敗了、狀態碼多少」就好,複雜的容錯邏輯留在呼叫端一次處理。這樣分工的好處是 fetchReadable 未來如果要換掉 Jina Reader、改用別的抓取服務,也不用去動任何降級邏輯,兩件事完全切開。

明天要處理另一個常見情境:同一個網址如果被我重複傳進來,line-notion-bot 怎麼判斷該新增一筆還是更新既有那筆,避免 Notion 裡堆出一堆重複資料。


上一篇
Day 12|免費模型隨時會掛:三層 fallback 設計
下一篇
Day 14|同一個網址不重複存:先查再決定新增或更新
系列文
用 LINE Bot 和 Agent Skill 自動化整理筆記與 IG 發文 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言