Apify 跟 ScraperAPI 都打不贏 Dcard 的 Cloudflare?先分清楚你看到的是 403 還是「Just a moment」
一句話: 被 Dcard 擋下來時,先看清楚畫面長怎樣——是立刻回一頁乾淨的錯誤訊息,還是先跳出「Just a moment…」的驗證畫面再拒絕你——這決定了換 proxy 有沒有用,也決定了你下一步該花錢在哪裡。
有人在 Threads 上問:Apify 跟 ScraperAPI 都打不動 Dcard
有人在 Threads 上問 n8n 社群:「請問 Threads 的 n8n 大神們是用什麼方式爬取用 cloudflare 保護的網站(好像 Dcard)? 試過用 Apify 跟 ScraperAPI 都失敗了」。
這個問題背後藏著一個常見的誤會:把「Apify」「ScraperAPI」當成單一工具在比較,好像其中一個能過、一個不能過。但 Apify 跟 ScraperAPI 都只是執行環境——你可以在上面跑最陽春的 HTTP 請求,也可以跑帶完整瀏覽器指紋的無頭瀏覽器,兩者面對 Cloudflare 的結果完全不同。真正該先搞清楚的,不是「哪個工具比較神」,而是自己被擋下來時,Cloudflare 用的是哪一層機制——因為不同層級,解法完全不一樣,而且不是每一層都能靠換 proxy 解決。
先分清楚:你看到的是「直接拒絕」還是「先驗證再拒絕」
Cloudflare 官方文件把 WAF 規則能採取的動作分成兩種,邏輯完全不同:
- Block(封鎖):直接回 403 Forbidden,沒有任何驗證流程。官方文件寫這個動作「carries minimal false positive risk」,通常用在信心分數很低、幾乎確定是機器人的流量。
- Challenge(驗證):不是直接拒絕,而是先給訪客一個機會證明自己是人。Cloudflare 的說明寫得很白:這是「一個介於訪客與目的地之間的關卡」,會先評估瀏覽器環境的自動化訊號,訪客「沒有通過驗證就到不了目的地」。這就是你會看到「Just a moment…」這種讀取畫面的來源——Cloudflare 的 Bot Management 文件說明這套機制會替每個請求打 1–99 分的機器人分數,分數落在 2–29 之間的「疑似自動化」流量,官方建議的處理方式就是 Managed Challenge,而不是直接封鎖。
這裡有個容易誤判的地方:Challenge 畫面本身也可能回 403 狀態碼。Cloudflare 自己的錯誤代碼說明寫得很直接:帶有 Cloudflare 品牌樣式的 403,可能是「WAF 自訂或代管規則採用 challenge 或 block 動作」(“WAF Custom or Managed Rules with the challenge or block action”)觸發的——換句話說,不是只有 Block 會回 403,Challenge 一樣可能回。Apify 官方學院的說明講得更具體:「Cloudflare 的 challenge 畫面在評估指紋的同時,仍然可能回傳 403 狀態碼,而請求並沒有真的被擋下」(“the Cloudflare challenge screen may return a 403 status code even if it is evaluating the fingerprint and the request is not blocked”)。也就是說,光看 HTTP 狀態碼不夠可靠,你得看回應內容本身:是一頁乾淨的錯誤訊息,還是含有 JS 驗證腳本、標題寫著「Just a moment…」的過渡畫面。
為什麼這個差異決定了換 proxy 有沒有用
| 情境一:乾淨的 403(Block) | 情境二:「Just a moment」(Challenge) | |
|---|---|---|
| 觸發原因 | WAF 規則判定流量幾乎確定是機器人,或 IP/ASN 被規則直接擋(官方文件) | Bot Management 給出中間分數(2–29),或速率限制觸發驗證(官方文件、Bot Management) |
| 回應內容 | 錯誤頁,沒有 JS 驗證流程 | 含 JS 驗證腳本、「Just a moment…」過渡畫面,通過後才拿到放行憑證(Cloudflare) |
| 換乾淨的 residential proxy 有沒有用 | 通常有用——問題核心是這個 IP/ASN 的信譽或請求量,換一個乾淨出口就繞過判定條件 | 不保證有用——就算 IP 乾淨,只要瀏覽器指紋沒生成好、或每次都重新產生不一致,一樣可能卡在 Cloudflare 的挑戰(Apify 官方文件) |
| 真正該花錢/花工程時間的地方 | Proxy 品質(datacenter → residential) | 瀏覽器指紋的一致性與真實性,而不是 proxy 本身 |
實例對照:LIHKG-scraper 遇到的是「情境一」等級的問題
拿連登爬蟲 LIHKG-scraper當對照最清楚。它的輸入欄位 proxyConfiguration 預設就開 Apify(datacenter)proxy,官方說明寫得很直接:「不用 proxy 時會跟平台上其他 run 共用出口 IP,LIHKG 會因為別人的流量對你限流(429、回覆缺頁)」。
這是典型的情境一:連登回應的是單純的流量/IP 信譽判定(429 Too Many Requests),沒有 JS 驗證畫面,也不要求瀏覽器指紋。解法對應的也是同一層——不是跳去 residential proxy,是把「不開 proxy」換成 Apify 內建的 datacenter proxy:不再共用平台的公用出口 IP 之後,這個 429 就直接解決,完全不需要動到瀏覽器層。
不過 datacenter proxy 也不是從此一勞永逸。作者自己另一隻共用同一套連線層的 actor,在 2026-09-05 量測到:即使走 datacenter proxy,LIHKG 的 Cloudflare 仍然會對其中一部分 session 套 429——連續開 15 個新 session,只有 6 個乾淨過關、其餘 9 個收到 429 挑戰頁。修法一樣不是往上跳去 residential,是遇到 403/429 就換一個新 session 重試;這仍然是「換出口 IP」這一層的邏輯,跟 Dcard 那種瀏覽器指紋層級的驗證不是同一回事。
Dcard 的 Cloudflare 防護才是不同量級的問題。如果你打過去看到的是「Just a moment…」而不是單純的錯誤頁或 429,那就已經進入情境二——這時候不管是換 datacenter 還是 residential proxy,都可能改善一部分(IP 信譽確實是評分因子之一),但不會是決定性的修正,因為卡住你的不是 IP,是瀏覽器指紋這一關。
確認自己在情境二之後,下一步該做什麼
如果診斷結果是「Just a moment」這種 JS 驗證畫面,Apify 官方學院的建議是把重心從 proxy 轉到瀏覽器指紋:
- 用 Crawlee 內建的指紋產生機制,而且保持指紋一致比頻繁更換更有效——官方文件直接寫「預設的瀏覽器指紋,有時候反而比每次重新產生的指紋更有效」,一直換指紋反而更像機器人行為。
- 把爬蟲對「被封鎖狀態碼」的預設處理拿掉(在 Crawlee 裡是把
sessionPoolOptions.blockedStatusCodes設成空陣列),因為前面講的,403 不代表真的被擋,可能只是驗證流程的一部分;拿掉預設處理之後,要自己補上等挑戰跑完再繼續、以及真的被判定封鎖時換一個新 session 重試的邏輯。 - 如果連瀏覽器指紋都對了,還是被丟出驗證碼(captcha),代表這個出口 IP 已經被判定為「疑似代理」(graylisted)——這時候如果手上 proxy 池夠大,換一個 session/IP 通常比較快;proxy 池小的話,才輪到 captcha 解碼服務這類更花錢的手段。
這也是為什麼「Apify 跟 ScraperAPI 都失敗了」這句話本身資訊量不夠——兩個都只是平台,真正決定結果的是有沒有走到「一致的瀏覽器指紋」這一步,光加 residential proxy 換不到這個東西。
挑一條開始
從最省事到最自由
FAQ
Apify 跟 ScraperAPI 都爬不動 Dcard,是不是代表這兩個工具本身不行? 不一定。Apify、ScraperAPI都只是執行環境/代理服務,真正決定能不能爬過的是你怎麼設定它們——用一般datacenter出口IP直接打,跟開residential proxy、或改用能執行完整JS的無頭瀏覽器,結果天差地遠。先確認自己卡在哪一層,比换工具更有效。
HTTP 403跟看到「Just a moment」的畫面,差在哪? 差在擋你的機制不同。Cloudflare官方文件寫的Block動作直接回403、沒有任何驗證流程;但Challenge動作(WAF規則、Bot Management評分、速率限制都可能觸發)也可能夾帶403狀態碼,只是頁面內容會換成「Just a moment…」的JS驗證畫面,瀏覽器要先跑完那段JS拿到cf_clearance才放行。所以光看狀態碼不夠,要看回應內容裡有沒有這段JS驗證頁。
換residential proxy可以解決Cloudflare的JS challenge嗎? 不一定能解決,但通常能降低觸發機率。Cloudflare自己的說明寫明,Challenge動作一樣可能回403,不是只有Block才會;Apify官方文件也明講,Cloudflare的challenge畫面在評估瀏覽器指紋時本身就可能回傳403、請求其實沒被真的擋下。proxy只是輸入之一,就算換了乾淨的住宅IP,只要瀏覽器指紋沒生成好、或每次都不一致,一樣可能被判定成自動化流量而卡關。
LIHKG-scraper預設就開proxy,是同一種問題嗎? 是同一個大類(反爬),但層級完全不同。LIHKG-scraper官方說明寫的是:不開proxy會跟平台其他run共用出口IP,因為流量太多被連登限流回429——這是單純的IP信譽/流量問題,換成Apify內建的proxy(datacenter層級,不需要跳到residential)就直接解決,不需要瀏覽器指紋這一層。Dcard的Cloudflare JS challenge是更高一層的驗證,兩者不能用同一套邏輯處理。
確定自己卡在JS challenge這一層,下一步該怎麼做? proxy已經不是重點,重點換成能不能生出一致、像真人的瀏覽器指紋。Apify官方文件建議用Crawlee內建的指紋產生機制,維持指紋一致而非每次都亂換,把預設的被封鎖狀態碼處理拿掉、自己補上等挑戰跑完再繼續與換session重試的邏輯;如果連指紋都對了還被丟驗證碼,代表IP已經被判定為疑似代理,這時候proxy池夠大就換session,池小才輪到captcha解碼服務這類更花錢的手段。
延伸閱讀
- GitHub 免費 proxy list 跟 Apify residential proxy 差在哪:確定自己卡在「情境一」該換乾淨 proxy 之後,這篇把免費清單、datacenter、residential 三條路的價格與存活率攤開比。
- 用 Apify + n8n + GPT 串論壇輿情 pipeline:如果你跟原 po 一樣是在 n8n 裡串資料來源,解決了爬取問題之後,這篇示範怎麼接下去做成自動化情緒監測。
作者 Chad 實際經營 40+ 隻上架 Apify actor,本文用到的 LIHKG-scraper 是其中之一;Cloudflare 的 Block/Challenge 機制差異全部引用官方文件與 Apify 官方學院的說明,查不到來源的細節這篇一律不寫。