| name | fb-blocker |
| description | 自動依關鍵字搜尋或名單在 Facebook 上批次封鎖特定用戶或專頁,並強制選取「封鎖___和對方可能建立的新個人檔案」選項以徹底封鎖。使用 Chrome DevTools MCP 工具。 |
Facebook 批次封鎖 (Facebook User/Page Blocker)
本 Skill 專門用於透過 Chrome DevTools MCP 工具自動化執行 Facebook 用戶與粉絲專頁的關鍵字搜尋、名單採集、逐一前往個人檔案頁面,並強制選取「封鎖 [用戶名] 和對方可能建立的新個人檔案」進行徹底封鎖與結果驗證。
核心前置條件與工具需求
- MCP 工具:
chrome-devtools-mcp
list_pages: 確認目前已開啟的 Facebook 頁面與 pageId。
navigate_page: 導航至搜尋頁面或各個人檔案頁面。
evaluate_script: 在頁面上下文中執行 DOM 抓取與非同步點擊封鎖流程。
- 環境要求:
- Chrome 瀏覽器需為已登入 Facebook 帳號的狀態。
標準執行 SOP (Standard Operating Procedure)
步驟 1:確認目前頁面狀態
- 呼叫
list_pages 找到 Facebook 頁面(例如 title: Facebook 或 url: https://www.facebook.com/...),記下其 pageId。
步驟 2:搜尋並擷取目標帳號名單
- 使用
navigate_page 前往搜尋頁面:
https://www.facebook.com/search/people?q=<URL編碼關鍵字>
- 執行以下滾動與名單採集腳本(透過
evaluate_script),將搜尋結果中符合名稱的所有個人檔案連結提取出來:
async () => {
const wait = (ms) => new Promise(r => setTimeout(r, ms));
const keyword = "目標關鍵字";
const urls = new Set();
let lastHeight = 0;
let noChangeCount = 0;
for (let i = 0; i < 30; i++) {
const links = Array.from(document.querySelectorAll('a[role="presentation"], a[role="link"]'));
for (const a of links) {
const text = a.innerText || a.textContent || '';
if (text.includes(keyword) && a.href && a.href.includes('facebook.com/')) {
try {
const u = new URL(a.href);
if (u.pathname === '/profile.php') {
urls.add(`${u.origin}${u.pathname}?id=${u.searchParams.get('id')}`);
} else {
urls.add(`${u.origin}${u.pathname}`);
}
} catch (e) {
urls.add(a.href.split('?')[0]);
}
}
}
window.scrollTo(0, document.body.scrollHeight);
await wait(1500);
const newHeight = document.body.scrollHeight;
if (newHeight === lastHeight) {
noChangeCount++;
if (noChangeCount >= 3) break;
} else {
noChangeCount = 0;
lastHeight = newHeight;
}
}
return Array.from(urls);
}
- 將擷取出的網址列表存檔或維持在佇列中,並進行去重處理。
步驟 3:逐一進行封鎖作業
對名單中的每個 URL,依序執行:
navigate_page 前往目標 URL。
- 呼叫
evaluate_script 執行以下標準封鎖腳本:
async () => {
const wait = (ms) => new Promise(r => setTimeout(r, ms));
if (document.body.innerText.includes('目前無法查看此內容') ||
document.body.innerText.includes('此內容目前無法顯示')) {
return { status: 'already_blocked_or_unavailable', checkedOption: '封鎖和對方可能建立的新個人檔案' };
}
let btn = null;
for (let i = 0; i < 12; i++) {
btn = Array.from(document.querySelectorAll('div[role="button"], button')).find(el => {
const aria = el.getAttribute('aria-label') || '';
return (aria.includes('查看更多') || aria.includes('個人檔案設定') || aria.includes() || aria.()) &&
!aria.() && !aria.() && !aria.() && !aria.();
});
(btn) ;
();
}
(!btn) {
(...() || ...()) {
{ : , : };
}
{ : , : };
}
btn.();
();
blockItem = ;
( i = ; i < ; i++) {
blockItem = .(.()).( {
text = (el. || el. || ).();
text === || text.();
});
(blockItem) ;
();
}
(!blockItem) { : , : };
blockItem.();
();
dialog = ;
( i = ; i < ; i++) {
dialog = .(.()).( {
aria = d.() || ;
text = d. || ;
aria.() || text.() || text.();
});
(dialog) ;
();
}
(!dialog) { : , : };
radios = .(dialog.());
targetRadio = ;
( r radios) {
parentContainer = r.() || r.;
(parentContainer && (parentContainer.?.() || parentContainer.?.())) {
targetRadio = r;
;
}
}
(!targetRadio && radios. >= ) {
targetRadio = radios[];
}
(targetRadio) {
targetRadio.();
} {
textEl = .(dialog.()).( {
el. && el..();
});
(textEl) textEl.();
}
();
confirmBtn = .(dialog.()).( {
aria = el.() || ;
text = (el. || ).();
aria === || text === || aria === || text === ;
});
(!confirmBtn) { : , : };
confirmBtn.();
();
successDialog = .(.()).( {
text = d. || ;
text.() || text.();
});
(successDialog) {
closeBtn = .(successDialog.()).( {
text = (el. || el.() || ).();
text === || text === ;
});
(closeBtn) closeBtn.();
}
{ : , : };
}
步驟 4:最終結果驗證
- 使用
navigate_page 重新前往搜尋頁面:
https://www.facebook.com/search/people?q=<URL編碼關鍵字>
- 滾動數次並檢查是否還有任何該關鍵字的連結:
async () => {
const wait = (ms) => new Promise(r => setTimeout(r, ms));
const keyword = "目標關鍵字";
window.scrollTo(0, document.body.scrollHeight);
await wait(1500);
window.scrollTo(0, document.body.scrollHeight);
await wait(1500);
const links = Array.from(document.querySelectorAll('a[role="presentation"], a[role="link"]'))
.map(a => ({ text: a.innerText, href: a.href }))
.filter(a => a.text && a.text.includes(keyword));
return { remainingCount: links.length, remainingLinks: links };
}
- 確認
remainingCount 為 0,向用戶回報最終處理結果。
例外狀況與處理策略
| 狀況 | 原因分析 | 應對方式 |
|---|
| 目前無法查看此內容 | 先前封鎖時選取了「連同可能建立的新個人檔案」,Facebook 已自動連帶封鎖該關聯帳號;或是該帳號已被刪除。 | 視為 already_blocked_or_unavailable,直接記錄為已封鎖並繼續處理下一個。 |
| 三點按鈕找不到 | 頁面尚未加載完全,或處於通知下拉視窗狀態。 | 腳本內建 12 次重試 (6秒);若仍失敗可重新呼叫 navigate_page 一次。 |
| 彈出對話框點擊失效 | Facebook 動態渲染延遲。 | 各動作間加入適當 wait(ms) 緩衝(500ms ~ 2200ms),確保網路請求完成。 |