怎麼有效率地找到適合合作的 Instagram 創作者
目的
Forest 的推廣(GTM,Go-To-Market,產品上市與推廣計畫)需要和 Instagram 上的創作者(網紅,又稱 KOL)合作。我們會先定好條件——哪個國家、什麼主題、多少追蹤人數——再找出所有符合的創作者,拿到他們的 Instagram 帳號名稱(handle,就是 @ 後面那串),方便後續聯絡。
目標是三件事:快(不用人工一個一個翻)、準(帳號真的符合條件)、全(盡量不要漏掉)。
1. 目前有三種方法
主要推薦① 搜尋引擎找候選+自己逐一確認
在公司 Mac mini 上開一個不登入任何帳號的瀏覽器,由程式自動操作:
- 找候選:到 Startpage(顯示 Google 的搜尋結果)和 Yahoo 台灣(顯示 Bing 的搜尋結果)用關鍵字搜尋,例如「
site:instagram.com 讀書帳 學測」,把結果裡出現的 Instagram 帳號全部收下來。 - 逐一確認:一個一個打開這些帳號的 Instagram 公開頁,讀出真實的粉絲數、自我介紹(bio)和最近一次發文的日期,再判斷是否符合條件。
目前不適用台灣② Instagram 官方「創作者市集」(Creator Marketplace)
Meta(Instagram 的母公司)在品牌後台 Meta Business Suite 裡提供的工具,可以依主題、粉絲數、受眾地區搜尋「主動登記願意接合作」的創作者。限制:只開放 18 個國家的創作者,沒有台灣;品牌要先有通過驗證的企業帳戶(business portfolio)。要量時再用③ 網紅資料庫工具(Kolr、Influencers.club)
付費的第三方服務,事先收錄了大量創作者資料,可以直接用國家、主題、追蹤人數篩選並匯出名單。最快、量最大,但要付月費。2. 什麼情況用哪個方法
| 方法 | 快 | 準 | 全 | 費用 | 適合情況 |
|---|---|---|---|---|---|
| ① 搜尋引擎+自己確認 | 中(一輪約 35 分鐘,機器自己跑) | 高(每個帳號都實際打開確認) | 中高(一輪找到全部 24 個中的 20 個) | 幾乎 0(不需額外付費) | 台灣、小眾主題、小型創作者;需要幾十個高品質名單 |
| ①+選配 AI 研究工具 | 多約 15 分鐘(可同時跑) | 高(帳號一樣回到第 2 步確認) | 再補文章型來源 | 每輪約 130–160 點(付費工具) | 想把推薦整理文、第三方網紅網站裡的帳號也撈進來 |
| ② 創作者市集 | 快 | 高(官方資料) | 只限有登記的創作者 | 免費(未查到使用費) | 目標國家在開放名單內(例如日本、韓國、印尼);目前不含台灣待確認 |
| ③ 網紅資料庫工具 | 快 | 中高 | 高 | 月費 | 需要大量名單、經常重複搜尋 |
3. 實際測試(2026-10-17)
測試條件:找台灣、主題是讀書/學習(俗稱「讀書帳」、studygram)、追蹤人數 1,000–50,000、最新貼文在 12 個月內(還有在經營)的 Instagram 創作者。所有帳號都用同一套標準,實際打開 Instagram 公開頁確認。
- 方法①:一輪 34 分鐘、不需額外付費點數,從 78 個候選中確認 20 個符合,佔全部 24 個確認帳號的 83%。
- 對照:另一個付費 AI 研究工具每輪 14–60 分鐘、約 130–160 點,最多找到 42%。
- 為什麼保留它當選配:有 4 個帳號只出現在推薦整理文、訪談、第三方網紅網站這類文章型來源,只有它找到。
24 個確認符合條件的帳號
| # | IG 帳號 | 粉絲 | 最新貼文 | 台灣/主題證據 | 找到的方式 |
|---|---|---|---|---|---|
| 1 | @117._.cap | 21K | 2026-10-12 | 117 會考生;讀書縮時、筆記 | 主要做法 |
| 2 | @_dream.study__ | 5,881 | 2026-08-25 | 陽明醫學;成大單車節校園大使 | 主要做法 |
| 3 | @baiyu.study_ | 1,195 | 2026-08-29 | 武陵高中;116 學測 | 主要做法 |
| 4 | @bi.daily.learning | 40K | 2026-10-10 | 蘭陽女中→台大;從讀書考試走入生活 | 選配工具 |
| 5 | @bingobilingual_bb | 30K | 2026-09-17 | 台大外文/口譯所;英文學習教學型創作者 | 選配工具 |
| 6 | @c2h4_study 原本已知 | 48K | 2026-10-15 | 北一數資→政大心理;《學霸筆記術》作者 | 選配工具 |
| 7 | @chu_chie.studygram | 2,897 | 2026-08-06 | 116 學測;成大單車節大使 | 選配工具 |
| 8 | @echonotes_.study | 2,449 | 2026-08-28 | 116 學測;公益筆記 | 主要做法 |
| 9 | @grantung | 30K | 2026-10-08 | 台大地理;國高中社會科講師(教學型) | 主要做法 |
| 10 | @iamxuanran | 13K | 2026-09-26 | 台灣大一新生;讀書與生活 | 主要做法 |
| 11 | @jin_yan._.study | 9,074 | 2026-09-20 | 台南女中→台大 | 主要做法 |
| 12 | @kitten._.study_115 | 8,380 | 2026-10-17 | 115 學測;大學普生普化+高中筆記 | 主要做法 |
| 13 | @ls_science | 8,144 | 2026-10-10 | 國中自然老師;會考(教學型) | 主要做法 |
| 14 | @meow_studynotes | 17K | 2026-08-30 | 北一女→早稻田;日本留學讀書帳 | 主要做法 |
| 15 | @ninii.study_ 原本已知 | 18K | 2026-10-16 | nini 的讀書帳 | 主要做法 |
| 16 | @popcornstudy__ | 7,349 | 2026-03-04 | 北一女中/醫學系;學測、會考 | 主要做法 |
| 17 | @rounincat_study | 2,842 | 2026-07-02 | 學生學習乾貨;成大單車節校園大使 | 主要做法 |
| 18 | @study.suan | 1,327 | 2026-10-07 | 研究所、司律國考讀書帳 | 主要做法 |
| 19 | @study_yu_rou_ | 11K | 2026-07-27 | 台大物理治療 | 主要做法 |
| 20 | @studysloth__ | 6,655 | 2026-10-12 | 台南女中→高醫 | 主要做法 |
| 21 | @tides_study | 23K | 2026-10-11 | 116 學測;讀書筆記 | 主要做法 |
| 22 | @weiyang_study | 12K | 2026-10-04 | 清大 | 主要做法 |
| 23 | @winnnnnie_study | 15K | 2026-03-13 | 台中;讀書日常 | 主要做法 |
| 24 | @xi_yu_studying_ | 24K | 2026-10-17 | 北一女→高醫藥學;國考生 | 主要做法 |
方法①的 78 個候選裡,沒通過的 58 個原因分布
| 判定 | 數量 | 說明 |
|---|---|---|
| 部分符合 | 13 | 台灣證據不足、主題混雜,或是考試倒數頁這類「受眾相關但不是個人創作者」的帳號 |
| 粉絲不在範圍 | 22 | 少於 1,000 或多於 50,000 |
| 已停更 | 8 | 最新貼文超過 12 個月 |
| 找不到帳號 | 6 | 帳號已刪除或改名 |
| 不是個人創作者 | 6 | 學校單位、出版社、補習班、品牌 |
| 主題不符 | 3 | 內容不是讀書/學習 |
4. 方法①怎麼做:搜尋引擎找候選+自己逐一確認
原理:先用搜尋引擎找出「可能符合」的帳號(候選名單,先不篩),再一個一個打開 Instagram 公開頁確認。整個流程可以自己手動做(幾十個帳號以內),也可以請 AI 助理(例如 Claude Code、Codex)在公司 Mac mini 上自動跑(程式已經寫好,見 For AI agents)。
步驟 1–2:定條件、找候選
- 寫下條件:國家、語言、主題、粉絲數範圍、「最新貼文在 12 個月內」。列出已經確認過的帳號,之後不用重查。
- 把主題拆成 6 個左右的小主題,每個小主題準備約 6 組關鍵字(下表是讀書帳的實際例子)。關鍵字前面加
site:instagram.com,意思是「只搜 Instagram 網站裡的頁面」。 - 到 Startpage 和 Yahoo 台灣搜尋:每組關鍵字兩個引擎都搜一次,每次搜尋之間停 4–8 秒。不要用 Google 首頁,自動搜尋時常跳出「我不是機器人」驗證;某個引擎跳出驗證就先不用它。
- 收集帳號:搜尋結果是個人頁(網址像
instagram.com/帳號/)就直接記下帳號;是單篇貼文(網址有/p/或/reel/)就打開貼文、記下發文者。這一步全部收下、不篩選。
| 小主題 | 關鍵字(每組前面都加 site:instagram.com 讀書帳) |
|---|---|
| 學測/分科 | 學測、GSAT、116學測、117學測、分科測驗、高中生 筆記 |
| 會考 | 會考、CAP 國中、117會考、118會考、國中 筆記分享;另搜 Threads:site:threads.com 讀書帳 會考 |
| 國考/研究所 | 國考、醫學系、藥學系、研究所、公職 高普考、律師 國考 |
| 語言/留學 | 多益、雅思、留學、日檢、英文 單字;另搜 site:instagram.com 英文學習 台灣 帳號 筆記 |
| 筆記/手帳 | 筆記 iPad、goodnotes、手帳、文具、筆記分享、collanote |
| 大學讀書日常 | 大學生、台大、自律、讀書縮時、成大單車節校園大使;另搜 site:instagram.com studygram 台灣 讀書帳 |
步驟 3:逐一確認
- 用沒有登入 Instagram 的瀏覽器(無痕視窗或程式控制的瀏覽器),在家裡或辦公室網路打開
https://www.instagram.com/帳號/。 - 記下三件事:①粉絲數(頁面上的「N 位粉絲」);②自我介紹裡的學校、城市、考試等台灣線索與主題;③最新一篇貼文的日期(置頂貼文可能是舊的,要看非置頂的)。順手截圖當證據。
- 放慢速度:每打開一頁停 3–8 秒,一輪最多約 150 頁(貼文頁也算)。
- 看到登入畫面、「請稍候幾分鐘」或「太多請求」就停,記下停在哪個帳號,隔天再繼續。不要登入、不要換網路或用其他方法繞過。
步驟 4:判斷標準與整理名單
| 條件 | 怎麼看 | 不符合時 |
|---|---|---|
| 帳號存在 | 頁面打得開,沒有「無法顯示」 | 找不到帳號 |
| 粉絲 1,000–50,000 | 以公開頁顯示的數字為準,不採用搜尋結果或其他工具回報的數字 | 粉絲不在範圍 |
| 在台灣 | 台灣的學校、城市、考試(學測、會考、統測、國考)或寫明 Taiwan | 證據不足 → 部分符合 |
| 主題是讀書/學習 | 自我介紹和最近貼文以讀書、筆記、考試、學習方法為主 | 主題不符;混雜 → 部分符合 |
| 是個人創作者 | 學生或老師本人經營;考試倒數頁、學校單位、出版社、補習班、品牌不算 | 不是個人創作者(倒數頁列為部分符合) |
| 還在經營 | 最新貼文在 12 個月內 | 已停更 |
- 全部符合才算「通過」;「部分符合」的另外列一張,人工決定要不要納入。
- 和之前的名單合併,標記這次新找到幾個、已知帳號有沒有找到,記下花的時間。
- 聯絡前再看一次:粉絲數和主題會變,合作前請人工再確認。
5. 方法②怎麼做:Instagram 創作者市集(Creator Marketplace)
Meta 官方的「創作者市集」:品牌在 Meta Business Suite 裡依條件搜尋願意接合作的創作者。也有官方 API 開放給開發者。品牌端自 2026-01-30 起全球可用;未查到使用費。
可以篩什麼
- 興趣主題
- 受眾年齡、性別、地區
- 追蹤數範圍
- 過往合作紀錄
- 相似創作者
使用條件
- 通過驗證的 business portfolio(企業管理資產組合)
- Instagram 商業帳號,並連結 Facebook 粉絲專頁
- 只涵蓋主動加入(opt-in)的創作者,超過 200 萬人
可以直接用 Business Suite 介面或官方 API,也可透過 impact.com 等平台。
待辦:到 Business Suite 確認一次 介面路徑未驗證
- 確認公司的 business portfolio 已驗證,且 Forest 的 IG 商業帳號已連結 FB 粉專。
- 登入 Meta Business Suite,找到 Creator Marketplace(創作者市集/品牌合作相關功能)。
- 在搜尋篩選中看:①創作者所在地能否選「台灣」;②受眾地區能否選「台灣」。
- 截圖記錄結果,更新本頁與 MAR-903。若可選台灣,再試搜「讀書/學習」主題。
6. 方法③:網紅資料庫工具比較
這類工具事先收錄大量帳號,可以直接用國家、主題、追蹤數篩選。速度和量最好,但要月費。
| 工具 | 定位 | 價格(研究時查得) | 備註 |
|---|---|---|---|
| Kolr(iKala) | 台灣在地首選 | TWD 15,000/月(未稅) | 台灣約 39.5 萬創作者;沒有公開 API,用介面篩選+匯出 CSV(每份名單上限 90 人);免費版只顯示前 4 筆。 |
| Influencers.club Discovery API | 可程式串接的選項 | 約 US$208–249/月 | 可依創作者所在地、追蹤數、語言、關鍵字搜尋;註冊送 10 免費 credits。試用待辦:需公司 email。台灣小帳覆蓋率未驗證 |
| Modash | 功能完整但太貴 | API US$16,200/年起 | 沒有月付方案。 |
| Apify | 便宜的自己動手方案 | 約 US$20–60/月 | hashtag/相似帳號爬取;有違反 IG 條款的風險(帳號/IP 封鎖)。 |
常見問題 FAQ
我不會寫程式,也能用嗎?
可以。少量時照第 4 節手動做:用 Startpage 或 Yahoo 台灣搜尋、用無痕視窗打開 IG 公開頁記下數字。量大時,把本頁網址交給 AI 助理(Claude Code、Codex 等),請它照最後的「For AI agents」執行,程式已經寫好。
一輪要多久、花多少錢?
方法①一輪約 35 分鐘,機器自己跑,不需額外付費點數;AI 助理用量若按 API 牌價約 US$4–6,用訂閱方案額度則幾乎不另外花錢。選配的 AI 研究工具每次約 15 分鐘、130–160 點。資料庫工具是月費。
為什麼不直接相信搜尋結果或 AI 給的粉絲數?
常常過時或錯誤(例:工具回報 18.6K,實際 8,380)。一律以實際打開公開頁看到的數字為準。
為什麼不在 Instagram 裡直接搜?
沒登入時,IG 的關鍵字搜尋和大部分 hashtag 頁都會要求先登入;用登入的帳號讓程式自動搜,則有違反條款、帳號被封的風險。
打開 IG 頁面跳出登入畫面,或顯示「請稍候幾分鐘」怎麼辦?
代表短時間內看太多頁了。立刻停下、記下停在哪個帳號,隔天再繼續;之後把每頁間隔拉長、一輪頁數減少。不要登入、換網路或用其他方法繞過。
搜尋引擎跳出「我不是機器人」驗證怎麼辦?
先停用那個引擎,改用另一個(Startpage 或 Yahoo 台灣),或隔一段時間再試。
為什麼要排除停更的帳號?
一年以上沒發文的帳號,合作後觸及和互動通常很低,創作者也可能不再回覆。判斷方式是看最新一篇(非置頂)貼文的日期。
考試倒數頁、補習班、出版社的帳號算不算?
本頁的名單只收個人創作者(學生或老師本人經營),這些帳號列為「部分符合」或「不是個人創作者」。它們的受眾可能跟 Forest 很相關,要不要另外列一張投放名單,由行銷決定。
結果可以直接拿去聯絡網紅嗎?
建議先人工看過。粉絲數和主題會變,聯絡前再確認一次。
名單多久要更新?
粉絲數和經營狀況會變,建議每次要發合作邀請前重跑「逐一確認」;想找新帳號時再重跑整個流程,只確認新出現的帳號即可。
Creator Marketplace 搜不到台灣創作者?
台灣目前不在可搜尋的市場內。改用方法①或③;搜「受眾在台灣」的外國創作者是否可行未驗證。
看不懂的名詞
- KOL
- Key Opinion Leader,網紅/意見領袖。
- Handle
- Instagram 帳號名稱,@ 後面那串,例如 @tides_study。
- 候選名單
- 先收下「可能符合」的帳號,還沒確認。
- site:
- 搜尋語法,
site:instagram.com表示只搜 Instagram 網站裡的頁面。 - Startpage/Yahoo 台灣
- 兩個搜尋引擎,分別顯示 Google 和 Bing 的搜尋結果,自動搜尋時比較不會跳驗證。
- 登入牆
- Instagram 要求先登入才給看內容的畫面。
- 不登入的瀏覽器/Headless 瀏覽器
- 沒有登入任何帳號、由程式自動操作的瀏覽器(例:用 Playwright 控制的 Chrome)。
- API/API key
- 讓程式和服務溝通的窗口;API key 是程式使用時出示的密碼,不可外流。
- CSV
- 用逗號分隔的表格檔,可用 Excel 或 Google Sheets 打開。
- 種子(Seed)
- 少量已確認的好帳號,當作起點去找相似帳號。
- Creator Marketplace
- Meta 官方的創作者市集,品牌可在 Business Suite 搜尋願意合作的創作者。
- Business portfolio
- Meta 的企業管理資產組合(原 Business Manager),需完成企業驗證。
For AI agents:如何執行
Default: Method 1 without Manus — headless, logged-out Chromium (Playwright) searches Startpage and Yahoo Taiwan with site:instagram.com queries, resolves post URLs to owners, then opens each public profile to read followers, bio and latest post date. Optional: one Manus candidate-only run for article-type sources; its handles go through the same verification. Method 3 only when scale is needed and budget is approved; Method 2 only for its 18 creator markets.
accounts/login), the message 「請稍候幾分鐘」, or HTTP 429: stop the run and record it — no retry, no IP change, no bypass. Never write creator emails or phone numbers to outputs. Never print, log or commit API keys; Manus key only from env MANUS_API_KEY; never auto-accept high-credit confirmations.Method 1 pipeline
- Queries: ~6 sub-topics × ~6 queries, pattern
site:instagram.com 讀書帳 <keyword>(full list in the JSON). Writequeries.tsvassub_topic<TAB>query. - Search: each query on Startpage
https://www.startpage.com/do/search?q={q}&language=zh-TWand Yahoo Taiwanhttps://tw.search.yahoo.com/search?p={q}&n=40, 4–8 s apart. Drop an engine that shows a captcha. Do not use Claude Code built-in WebSearch for this (ignoressite:); google.com, Brave, DuckDuckGo block headless. - Extract: handles from
instagram.com/<handle>/URLs and(@handle)/@handlein snippets; post shortcodes from/p/and/reel/. Resolve each post to its owner by openinginstagram.com/p/<code>/logged out (counts toward the 150-page cap). - Verify: open
https://www.instagram.com/<handle>/; readmeta[property="og:description"](e.g. 「21K 位粉絲」), bio text, and up to 12 post shortcodes; latest post date = max of decoded shortcodes ((media_id >> 23) + 1314220021721ms). Screenshot each profile. Redact emails/phones before saving. - Judge: pass only if exists + 1,000–50,000 followers (public page) + Taiwan evidence + study topic + individual creator + latest post within 12 months. Otherwise
partial / fail-range / fail-inactive / fail-notfound / fail-topic / fail-not-creator. A human reviews every pass before outreach. - Report: candidates, passes, known-account coverage, new handles vs the existing union, minutes for discovery vs verification, cost, page count, and stop reason if any.
Scripts on the Mac mini (/Users/shaokanpi/clawd/docs/research/manus-kol-search/scripts/): search_harvest.py → n1b_candidates.py → ig_post_owner.py → ig_public.py → spotcheck.py → judgement → union.py. Condensed, self-contained versions below.
Reference: search (Playwright)
#!/usr/bin/env python3
"""Find candidate IG handles via Startpage + Yahoo Taiwan (condensed from scripts/search_harvest.py).
Usage: python3 ig_search.py queries.tsv out.json # queries.tsv: sub_topic<TAB>query per line
Rules: 4-8 s between searches; an engine that shows a captcha is dropped for the rest of the run.
"""
import json, random, re, sys, time, urllib.parse
from playwright.sync_api import sync_playwright
ENGINES = {"startpage": "https://www.startpage.com/do/search?q={}&language=zh-TW",
"yahoo": "https://tw.search.yahoo.com/search?p={}&n=40"}
SKIP = {"p", "reel", "reels", "explore", "accounts", "stories", "tv", "popular", "about", "legal", "direct", "web", "developer"}
H = r"[A-Za-z0-9._]{2,30}"
BLOCK = re.compile(r"captcha|unusual traffic|are you a robot|異常流量|請證明您不是機器人", re.I)
queries = [l.rstrip("\n").split("\t", 1) for l in open(sys.argv[1], encoding="utf-8") if "\t" in l]
results, dead = [], set()
with sync_playwright() as p:
b = p.chromium.launch(headless=True)
ctx = b.new_context(locale="zh-TW") # no cookies, not logged in
for topic, q in queries:
for eng, tmpl in ENGINES.items():
if eng in dead:
continue
pg = ctx.new_page()
pg.goto(tmpl.format(urllib.parse.quote(q)), wait_until="domcontentloaded", timeout=30000)
pg.wait_for_timeout(2500)
if BLOCK.search(pg.content()) and "instagram.com" not in pg.content():
dead.add(eng); pg.close(); continue
links = pg.evaluate("""() => [...document.querySelectorAll('a[href]')].map(a => {
let h = a.getAttribute('href') || ''; const m = h.match(/RU=([^/]+)/);
if (m) { try { h = decodeURIComponent(m[1]); } catch (e) {} }
const box = a.closest('li, .w-gl__result, .result, div.dd, div.algo') || a.parentElement;
return {href: h, text: (box ? box.innerText : '').slice(0, 600)};
}).filter(x => x.href.includes('instagram.com'))""")
for it in links:
found = set(re.findall(r"\(@(" + H + r")\)", it["text"])) | set(re.findall(r"(?<![\w.])@(" + H + r")", it["text"]))
m = re.search(r"instagram\.com/(" + H + r")", it["href"])
if m:
found.add(m.group(1))
post = re.search(r"instagram\.com/(?:" + H + r"/)?(?:p|reel)/([\w-]+)", it["href"])
handles = sorted({f.lower().strip(".") for f in found} - SKIP)
results.append({"topic": topic, "engine": eng, "query": q, "url": it["href"],
"handles": handles, "post": post.group(1) if post else None})
pg.close()
time.sleep(random.uniform(4, 8))
b.close()
json.dump(results, open(sys.argv[2], "w", encoding="utf-8"), ensure_ascii=False, indent=1)
print("dead engines:", dead)
Reference: verification (Playwright)
#!/usr/bin/env python3
"""Logged-out public IG profile check (condensed from scripts/ig_public.py).
Usage: pip install playwright && playwright install chromium
python3 ig_verify.py OUTDIR handle1 handle2 ...
Rules: 3-8 s between pages, max 150 pages per round, stop on login wall / 429.
"""
import datetime, json, random, re, sys, time
from pathlib import Path
from playwright.sync_api import sync_playwright
B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
EMAIL = re.compile(r"[\w.+-]+@[\w-]+\.[\w.]+")
PHONE = re.compile(r"(?<!\d)(?:\+?886[-\s]?|0)9\d{2}[-\s]?\d{3}[-\s]?\d{3}(?!\d)")
redact = lambda s: PHONE.sub("[phone]", EMAIL.sub("[email]", s or ""))
def shortcode_date(sc): # post shortcode -> post date, no extra page load
n = 0
for c in sc[:11]:
n = n * 64 + B64.index(c)
return datetime.date.fromtimestamp(((n >> 23) + 1314220021721) / 1000).isoformat()
out = Path(sys.argv[1]); out.mkdir(parents=True, exist_ok=True)
handles = list(dict.fromkeys(h.lower().lstrip("@") for h in sys.argv[2:]))[:150]
res, stop = [], None
with sync_playwright() as p:
b = p.chromium.launch(headless=True)
ctx = b.new_context(locale="zh-TW") # fresh context: no cookies, not logged in
for i, h in enumerate(handles):
if i:
time.sleep(random.uniform(3, 8))
pg = ctx.new_page(); r = {"handle": h}
resp = pg.goto(f"https://www.instagram.com/{h}/", wait_until="domcontentloaded", timeout=45000)
pg.wait_for_timeout(3500)
body = pg.evaluate("() => document.body ? document.body.innerText.slice(0, 1500) : ''")
r["followers"] = pg.evaluate("() => (document.querySelector('meta[property=\"og:description\"]')||{}).content || null")
r["bio"] = redact(body)
codes = pg.evaluate("() => [...document.querySelectorAll('a[href*=\"/p/\"],a[href*=\"/reel/\"]')]"
".map(a => (a.getAttribute('href').match(/\\/(?:p|reel)\\/([\\w-]+)/)||[])[1]).filter(Boolean)")
r["latest_post"] = max((shortcode_date(c) for c in codes[:12]), default=None)
pg.screenshot(path=str(out / f"{h}.png"))
if (resp and resp.status == 429) or "accounts/login" in pg.url or "請稍候幾分鐘" in body:
stop = f"blocked at {h}"; r["blocked"] = True # stop the run; no retry, no IP change
elif "無法顯示" in body or "此連結可能故障" in body:
r["not_found"] = True
res.append(r); pg.close()
if stop:
break
b.close()
(out / "ig_public.json").write_text(json.dumps(res, ensure_ascii=False, indent=1))
print(f"pages={len(res)} stop={stop}")
Optional Manus add-on (API)
MANUS_API_KEY. Never paste it into Slack, chat, documents, email, screenshots or code. If it leaks: delete it in Settings → API immediately, create a new one, and update every place that uses it.Candidate-only prompt (replace the [brackets]; list already-verified handles to exclude):
Goal: collect as many CANDIDATE Instagram creators as possible who may match: - based in [COUNTRY, e.g. Taiwan], posting in [LANGUAGE, e.g. Traditional Chinese] - about [MIN, e.g. 1,000]–[MAX, e.g. 50,000] followers - topic: [TOPIC, e.g. 讀書帳 / studygram / 學習方法 / 筆記 / 自律] Do NOT filter or verify follower counts. I will verify every account myself. Include every handle you find, even if uncertain. Use public sources only; never log in, never create accounts, never follow/like/comment/message anyone. Do not ask me questions. Split the search into these sub-topics and cover each one (in parallel sub-agents / a parallel workflow if you can): 1. [SUB-TOPIC 1, e.g. 學測 / 分科測驗 / 高中讀書帳] 2. [SUB-TOPIC 2, e.g. 會考 / 國中讀書帳] 3. [SUB-TOPIC 3, e.g. 國考 / 研究所 / 醫學系・藥學系讀書] 4. [SUB-TOPIC 4, e.g. 多益 / 雅思 / 語言學習帳] 5. [SUB-TOPIC 5, e.g. 筆記 / 手帳 / 文具 / iPad 筆記] 6. [SUB-TOPIC 6, e.g. 大學生讀書日常 / 自律 / study with me] For each sub-topic use many query variants, e.g. `site:instagram.com [KEYWORD] <sub-topic>`, `site:threads.com [KEYWORD] <sub-topic>`, plus Dcard / PTT / blog roundups, public KOL stats sites (e.g. Kolr, StarNgage), and links between accounts (campus ambassador lists, shout-outs, "friends" highlights). You may write code in your sandbox to extract handles in bulk. Exclude these already-known accounts: [LIST, or "none"]. Deliverable (attach the file): candidates.csv with columns exactly: ig_username, sub_topic, source_url, reported_follower_count (as seen in the source, may be wrong), country_hint, topic_hint Also give a short summary: queries per sub-topic and number of unique candidates.
Use the candidate-only prompt above. Header x-manus-api-key: YOUR_MANUS_API_KEY. POST /v2/task.create (never retry) → poll task.detail + task.listMessages every 30 s until status == "stopped" and no background jobs; waiting_for_event_type == "cascadeJobCall" is normal, any other waiting type → stop and ask a human. Download attachments immediately (temporary URLs). Keep only ig_username; verify with steps 3–5. Expected ~160 credits, ~14 min. Free accounts are forced to the lite profile. Reference runner with budget cap: scripts/run_task.py.
Background and sources
- Manus has no Meta/Instagram first-party data (no connectors installed). Meta announced acquiring Manus on 2025-12-29; China ordered the deal unwound on 2026-04-27; Manus resumed independent operation on 2026-09-01.
- Creator Marketplace 18-market list (no Taiwan): Manus blog, 2026-03 (source); also reachable via a Manus connector, which needs business OAuth.
Acceptance checks
- Handles unique and normalized (lowercase, no @).
- Every pass verified on the public page in this round; followers in range; latest post within 12 months.
- Taiwan evidence, topic, creator type recorded per handle.
- No emails, phone numbers, keys or tokens in outputs; ≤150 Instagram pages per round; stop reason recorded.
Structured workflow (JSON)
{
"workflow": "instagram-kol-search-by-criteria",
"version": "2026-10-17-v3",
"context": "MAR-903 Forest GTM. Example criteria: Taiwan, Traditional Chinese, study topic (讀書帳 / studygram), 1,000-50,000 followers, latest post within 12 months.",
"decision": {
"default": "method_1_search_engine_plus_local_verification (no Manus needed)",
"optional_add_on": "manus_article_candidates: run once only to pick up candidates from roundup articles, interviews and third-party KOL sites; send its handles to method_1 step_2 verification",
"scale_needed_and_budget_approved": "method_3_database_tools",
"creator_market_in_creator_marketplace_list": "method_2_instagram_creator_marketplace",
"taiwan_in_creator_marketplace": "not in the 18-market list (as of 2026-03); a human must check Meta Business Suite"
},
"guardrails": [
"Never log in to Instagram or Meta, never create accounts, never follow, like, comment or message anyone.",
"Never print, log or commit API keys or tokens. Manus key is read only from env MANUS_API_KEY.",
"Never write creator emails or phone numbers into any output; redact them as [email] / [phone].",
"Instagram login wall (redirect to accounts/login), the message 請稍候幾分鐘, or HTTP 429: stop the whole run, record where it stopped, do not retry, do not change IP, do not bypass.",
"Search engine shows a captcha: drop that engine for the rest of the run.",
"Manus: never buy credits or upgrade, never auto-accept high-credit confirmations."
],
"method_1_search_engine_plus_local_verification": {
"runtime": "Machine on a home or office network (tested on a Mac mini). Python 3 + Playwright Chromium, headless, fresh browser context with no cookies, not logged in, locale zh-TW.",
"step_1_discover": {
"engines": {
"startpage": "https://www.startpage.com/do/search?q={query}&language=zh-TW",
"yahoo_tw": "https://tw.search.yahoo.com/search?p={query}&n=40"
},
"engine_notes": "Startpage returns Google results and usually links profile pages; Yahoo Taiwan returns Bing results and mostly links post pages. google.com, Brave and DuckDuckGo show captchas or error pages in headless mode.",
"do_not_use": "Claude Code built-in WebSearch for Instagram discovery: it ignores site:instagram.com (tested: 144 queries, 14 candidates, 1 pass).",
"interval_seconds": [
4,
8
],
"query_pattern": "site:instagram.com 讀書帳 <keyword>",
"sub_topics": {
"t1_gsat": [
"site:instagram.com 讀書帳 學測",
"site:instagram.com 讀書帳 GSAT",
"site:instagram.com 讀書帳 116學測",
"site:instagram.com 讀書帳 117學測",
"site:instagram.com 讀書帳 分科測驗",
"site:instagram.com 讀書帳 高中生 筆記"
],
"t2_cap": [
"site:instagram.com 讀書帳 會考",
"site:instagram.com 讀書帳 CAP 國中",
"site:instagram.com 讀書帳 117會考",
"site:instagram.com 讀書帳 118會考",
"site:instagram.com 國中 讀書帳 筆記分享",
"site:threads.com 讀書帳 會考"
],
"t3_exam": [
"site:instagram.com 讀書帳 國考",
"site:instagram.com 讀書帳 醫學系",
"site:instagram.com 讀書帳 藥學系",
"site:instagram.com 讀書帳 研究所",
"site:instagram.com 讀書帳 公職 高普考",
"site:instagram.com 讀書帳 律師 國考"
],
"t4_lang": [
"site:instagram.com 讀書帳 多益",
"site:instagram.com 讀書帳 雅思",
"site:instagram.com 讀書帳 留學",
"site:instagram.com 讀書帳 日檢",
"site:instagram.com 英文學習 台灣 帳號 筆記",
"site:instagram.com 讀書帳 英文 單字"
],
"t5_notes": [
"site:instagram.com 讀書帳 筆記 iPad",
"site:instagram.com 讀書帳 goodnotes",
"site:instagram.com 讀書帳 手帳",
"site:instagram.com 讀書帳 文具",
"site:instagram.com 讀書帳 筆記分享",
"site:instagram.com 讀書帳 collanote"
],
"t6_uni": [
"site:instagram.com 讀書帳 大學生",
"site:instagram.com 讀書帳 台大",
"site:instagram.com 讀書帳 自律",
"site:instagram.com 讀書帳 讀書縮時",
"site:instagram.com studygram 台灣 讀書帳",
"site:instagram.com 讀書帳 成大單車節校園大使"
]
},
"volume_tested": "36 queries x 2 engines = 72 searches, 11 minutes, no captcha",
"extract": [
"handle from instagram.com/<handle>/ or threads.com/@<handle> URLs",
"handles in titles/snippets: '(@handle)', '<handle> on Instagram', '@handle'",
"post shortcodes from instagram.com/p/<code>/ and /reel/<code>/ URLs"
],
"skip_path_segments": [
"p",
"reel",
"reels",
"explore",
"accounts",
"stories",
"tv",
"popular",
"about",
"legal",
"direct",
"web",
"developer"
],
"resolve_posts": "Open https://www.instagram.com/p/<code>/ logged out and read the owner handle from the page meta tags. Same 3-8 s interval; these pages count toward the 150-page cap.",
"normalize": "lowercase, strip @, de-duplicate, remove handles already verified in earlier rounds"
},
"step_2_verify": {
"url": "https://www.instagram.com/<handle>/",
"interval_seconds": [
3,
8
],
"max_instagram_pages_per_round": 150,
"wait_after_load_ms": 3500,
"read": [
"meta[property='og:description'] -> follower display, e.g. '21K 位粉絲' or '5,881 位粉絲'",
"bio text from the page body (redact emails/phones before saving)",
"up to 12 post/reel shortcodes linked on the profile"
],
"latest_post_date": "For each shortcode: decode the first 11 chars with alphabet 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' into an integer media id; timestamp_ms = (id >> 23) + 1314220021721. Latest post = max date. No extra page loads.",
"not_found_markers": [
"無法顯示",
"此連結可能故障"
],
"stop_markers": [
"final URL contains accounts/login",
"請稍候幾分鐘",
"HTTP 429"
],
"evidence": "save one screenshot per handle",
"volume_tested": "78 candidate profiles + 48 post pages = 126 pages, 20 minutes, no login wall, no 429"
},
"step_3_judge": {
"pass_requires_all": [
"account exists",
"followers 1,000-50,000 as shown on the public page (never use counts from search results, Manus or other tools)",
"Taiwan evidence: Taiwan school or city, Taiwan exams (學測/會考/統測/國考/GSAT/CAP), Taiwan university, or 'Taiwan' in bio",
"current content is study / learning",
"individual creator (student or teacher-creator); not a countdown page, school unit, publisher, cram school or brand",
"latest post within 12 months of the check date"
],
"verdicts": {
"pass": "meets all criteria",
"partial": "Taiwan evidence weak, topic mixed, or a non-personal but highly relevant community page (e.g. exam countdown pages)",
"fail-range": "followers outside 1,000-50,000",
"fail-inactive": "latest post older than 12 months",
"fail-notfound": "page does not exist",
"fail-topic": "not study / learning",
"fail-not-creator": "organization, brand, publisher, cram school"
},
"human_review": "A human reads topic, Taiwan evidence and creator type for every pass before outreach."
},
"step_4_output": {
"files": [
"candidates.csv",
"ig_public.json (raw, redacted)",
"screenshots/<handle>.png",
"judgement.csv"
],
"judgement_columns": [
"handle",
"followers",
"latest_post",
"taiwan_evidence",
"topic",
"verdict",
"note"
],
"union": "merge pass rows with earlier rounds; record found_by per handle",
"report": [
"candidates",
"passes",
"pass rate",
"coverage of known in-range accounts",
"new handles vs earlier union",
"minutes for discovery vs verification",
"cost"
]
}
},
"optional_manus_article_candidates": {
"when": "Want extra candidates from roundup articles, interviews, third-party KOL sites (the weak spot of method_1).",
"prompt": "Sub-topic candidate-only prompt in the For AI agents section, under Optional Manus add-on: collect only, no filtering, exclude known handles, deliver candidates.csv.",
"expected": "about 160 credits and 14 minutes per run (EF1, 2026-10-17)",
"use_output": "Take only the ig_username column; ignore Manus follower counts and verdicts; verify every handle with method_1 step_2.",
"api": {
"base_url": "https://api.manus.ai",
"auth_header": {
"x-manus-api-key": "YOUR_MANUS_API_KEY"
},
"credits": "GET /v2/usage.availableCredits",
"create": "POST /v2/task.create body {\"message\":{\"content\":\"<PROMPT>\"}}; never retry create",
"detail": "GET /v2/task.detail?task_id=<ID>",
"messages": "GET /v2/task.listMessages?task_id=<ID>&order=desc&limit=100 (attachments[].url are temporary; download immediately)",
"stop": "POST /v2/task.stop body {\"task_id\":\"<ID>\"}",
"polling": "every 30 s until status == 'stopped' and has_running_background_jobs == false; waiting_for_event_type == 'cascadeJobCall' is normal; any other waiting type -> stop and ask a human",
"free_account_profile": "lite (forced)"
}
},
"scripts_on_mac_mini": {
"root": "/Users/shaokanpi/clawd/docs/research/manus-kol-search/scripts",
"search_harvest.py": "search_harvest.py queries.tsv OUT.json (queries.tsv: track<TAB>query per line; Startpage + Yahoo TW; 4-8 s; drops an engine on captcha)",
"n1b_candidates.py": "n1b_candidates.py RUN_DIR (raw search JSON -> candidates_n1b.csv + unresolved_posts.csv)",
"ig_post_owner.py": "ig_post_owner.py OUT.json code... (post shortcode -> owner handle; 3-8 s; stops on block)",
"ig_public.py": "ig_public.py OUTDIR [--max 150] handle... (profile followers, bio, latest post date, screenshot; 3-8 s; stops on login wall/429; redacts emails/phones)",
"spotcheck.py": "spotcheck.py OUTDIR/ig_public.json > spotcheck_raw.csv",
"union.py": "union.py (runs/*/judgement.csv -> union_verified.csv with found_by)",
"run_task.py": "optional Manus runner with budget cap, lock and ledger; never auto-confirms"
},
"measured_2026_10_17": {
"union_verified_handles": 24,
"A0_manus_baseline": {
"minutes": 59.8,
"credits": 132,
"delivered": 12,
"passes": 10,
"known_in_range": "2/3",
"union_share": "42%"
},
"EF1_manus_subtopics": {
"minutes": 13.7,
"credits": 157,
"delivered": 13,
"passes": 9,
"known_in_range": "1/3",
"union_share": "38%"
},
"N1_no_manus": {
"minutes": 34.0,
"minutes_discovery": 21.4,
"minutes_verification": 12.6,
"manus_credits": 0,
"claude_usd_estimate": "4-6 at API list price",
"candidates": 78,
"passes": 20,
"known_in_range": "1/3",
"union_share": "83%",
"only_found_by_N1": 12
},
"B1_manus_ig_native": {
"passes": 0,
"note": "Instagram in-app search blocked by login wall; do not use"
},
"N2_seed_expand_from_bio_mentions": {
"candidates": 7,
"passes": 0,
"note": "bios are truncated; mentions are mostly brands/organizations; not recommended"
},
"known_in_range_accounts": [
"c2h4_study",
"ninii.study_",
"study.msh"
],
"rule_change": "Inactive rule (latest post within 12 months) applied to all runs; study_penguin109, yu._.study.0 (EF1) and shannie.studie (B1) changed to fail-inactive."
},
"untested": [
"Running discovery and verification in parallel (estimated ~20 minutes instead of 34).",
"Whether Startpage / Yahoo Taiwan start blocking headless browsers at higher volume."
],
"acceptance_checks": [
"candidate handles unique and normalized (lowercase, no @)",
"every pass verified on the public page in this round: followers in range, latest post within 12 months",
"Taiwan evidence, topic and creator type recorded per handle",
"no emails, phone numbers, keys or tokens in any output",
"page count per round <= 150; stop reason recorded if the run stopped early",
"report candidates, passes, known-account coverage, new handles, discovery vs verification minutes, cost"
],
"open_items": [
"Check Meta Business Suite: is Taiwan selectable as creator location or audience location in Creator Marketplace",
"Influencers.club trial needs a company email",
"Decide whether countdown pages / cram schools / publishers (non-KOL but relevant audience) become a separate ad list"
]
}