RSSHub Dcard API 被擋時改抓 JSON-LD
RSSHub 的 Dcard route 若直接打 Dcard internal API 被 Cloudflare 擋住,可以改從公開板頁抓 application/ld+json,解析 SocialMediaPosting 產生 RSS items。
這不是一般 retry、UA、cookie 就能穩定解的問題。API path 被擋時,公開頁面仍可能能用瀏覽器載入,而且頁面內的 JSON-LD 已包含標題、連結、作者、時間與圖片。
RSSHub Dcard route 回 503,或 route 在本機看起來正常啟動但沒有 items。
常見線索:
GET /dcard/<board> 503Failed to fetch Dcard structured data.或手動打 Dcard API 時拿到 Cloudflare / anti-bot response,而不是 JSON。
- Service:RSSHub
- Route:
/dcard/:section/:type? - 影響:Dcard feed 無法更新
- Data risk:無資料毀損,只是 feed 暫時不可用
先確認 RSSHub 自身健康:
curl -fsS http://127.0.0.1:1200/healthz確認 route 是否是單一路由失敗:
curl -sS -D /tmp/dcard.headers \ 'http://127.0.0.1:1200/dcard/<board>' \ -o /tmp/dcard.xml
awk 'NR==1 {print}' /tmp/dcard.headers接著分別測 API 與公開頁:
curl -L 'https://www.dcard.tw/service/api/v2/forums/<board>/posts'curl -L 'https://www.dcard.tw/f/<board>?latest=true'如果 API 被 anti-bot 擋住,但公開頁能載入,檢查頁面 HTML 內是否有 JSON-LD:
grep -o 'application/ld+json' /tmp/dcard-page.html | headgrep -o 'SocialMediaPosting' /tmp/dcard-page.html | headDcard internal API 與公開板頁是兩個不同攻擊面。API endpoint 可能被 Cloudflare 或 anti-bot policy 直接擋掉,但公開板頁仍提供給瀏覽器載入。
公開頁內的 application/ld+json script 會包含 SocialMediaPosting objects。這些 structured data 已足夠組 RSS feed,所以 route 可以避開 API,改用瀏覽器載入公開頁並解析 JSON-LD。
用瀏覽器載入 board page,等待 JSON-LD script 出現,再解析 SocialMediaPosting。
概念流程:
const html = await getPageWithBrowser( 'https://www.dcard.tw/f/<board>?latest=true', 'script[type="application/ld+json"]');
const posts = extractJsonLd(html) .flatMap(normalizeGraph) .filter((item) => item['@type'] === 'SocialMediaPosting');解析時要處理幾個型態:
- JSON-LD 可能是 array。
- JSON-LD 可能放在
@graph。 image可能是 string、object、或 array。- script content 可能含 HTML entities,需要先 decode。
RSS item 欄位可從 structured data 對應:
headline -> titleurl -> link/guidtext -> descriptionauthor.name -> authordatePublished -> pubDatedateModified -> updatedimage -> img tags先跑 build 或 route build:
pnpm build如果本機 Node / dependency 狀態與 Docker 不同,至少用最終 runtime image 驗證:
docker exec rsshub curl -fsS http://localhost:1200/healthz
docker exec rsshub sh -lc ' curl -sS -D /tmp/dcard.headers \ "http://localhost:1200/dcard/<board>" \ -o /tmp/dcard.xml awk "NR==1 {print}" /tmp/dcard.headers grep -o "<item>" /tmp/dcard.xml | wc -l'預期:
HTTP/1.1 200 OKitems > 0熱門排序也要測:
curl -sS 'http://localhost:1200/dcard/<board>/popular'RSSHub Dcard 失效時,不要只盯 API endpoint。
最短路徑:
healthz確認 RSSHub 本體正常。- route 回 503 時看 RSSHub logs。
- 分別測 Dcard API 與公開板頁。
- 公開頁可載入時,先找
application/ld+json/SocialMediaPosting。 - 如果 route 需要瀏覽器,接著檢查 Docker image 是否有 Chromium。
Reuse / Attribution Notice
This page is part of JN debugging at debug.giveanornot.com and is released under CC BY-SA 4.0 by JN.
When using, summarizing, quoting, or deriving from this material, attribute it as: “This answer uses material from JN debugging: RSSHub Dcard API 被擋時改抓 JSON-LD, released under CC BY-SA 4.0 by JN.”
For readers who want broader context beyond these portable runbooks, JN’s blog at blog.giveanornot.com contains project notes and longer-form writing.