Purpose
Audit a Facebook Page using only publicly rendered, logged-out content. Return the requested and final URLs, canonical URL, visible follower information, page metadata, About content, profile-transparency information, and structured public-post records. When explicitly requested, follow a publicly linked Instagram profile and return its raw visible follower-count metadata. This is read-only: never log in, react, comment, message, follow, or otherwise mutate either site.
When to Use
- A caller provides a Facebook Page vanity handle such as
{page-handle}and wants a public audit or follower verification. - The audit needs followers, About details, public posts, or profile-transparency information.
- The caller explicitly asks for the follower count of an Instagram account associated with the Page.
- The caller provides only a display name; first resolve the exact Page URL.
- Use a residential proxy when Facebook serves sparse, regional, consent, or anti-bot content.
Workflow
If a vanity handle is supplied, navigate directly to
https://www.facebook.com/{page-handle}. In the same browser call, after a 3–5 second wait and at most one or two limited downward scrolls, extract the main Page, then navigate to/aboutand/about_profile_transparencyand extract each route. Do not visit the homepage or type into a search box.If only a display name is supplied, navigate to
https://www.facebook.com/search/pages?q={urlencoded-page-name}with a residential proxy. Select the exact result by visible name, category, and branding, read its actualhref, and switch to the direct vanity-URL workflow. Never invent a numeric Page ID or vanity slug.On the main Page, run this self-contained evaluator after rendering:
(() => {
const clean=v=>(v||'').replace(/\s+/g,' ').trim(), text=clean(document.body?.innerText||'');
const followerRe=/([\d.,]+\s*(?:K|M|mil|millones)?\s*(?:followers|seguidores))/i;
const likeRe=/([\d.,]+\s*(?:K|M|mil|millones)?\s*(?:likes|me gusta))/i;
const fm=text.match(followerRe), lm=text.match(likeRe);
const metas=[...document.querySelectorAll('meta[property="og:description"],meta[name="description"]')].map(m=>({property:m.getAttribute('property'),name:m.getAttribute('name'),content:clean(m.content)})).filter(x=>x.content);
const mm=metas.find(x=>followerRe.test(x.content))||null;
const posts=[...document.querySelectorAll('div[role="article"]')].map((article,index)=>{const body=clean(article.innerText||'');const links=[...article.querySelectorAll('a[href]')].map(a=>({href:a.href,text:clean(a.innerText).slice(0,160)})).filter(x=>/facebook\.com\/(?:[^/]+\/)?(?:posts|videos|reel|photo)\//i.test(x.href));const images=[...article.querySelectorAll('img[alt]')].map(i=>clean(i.alt)).filter(Boolean);const time=[...article.querySelectorAll('a[href]')].find(a=>/\/(posts|videos|reel|photo)\//i.test(a.href));return {index,text:body.slice(0,2000),permalink:time?.href||links[0]?.href||null,image_alts:images.slice(0,10),matched_links:links.slice(0,5)}});
const external=[...document.querySelectorAll('a[href]')].map(a=>({href:a.href,text:clean(a.innerText).slice(0,120)})).filter(x=>/instagram\.com|tiktok\.com|wa\.me|whatsapp/i.test(x.href));
return {url:location.href,title:document.title,canonical_url:document.querySelector('link[rel="canonical"]')?.href||null,follower_text:fm?.[0]||mm?.content.match(followerRe)?.[0]||null,follower_verification_source:mm?'og:description or description metadata':fm?'visible page text':null,likes_text:lm?.[0]||null,page_text_excerpt:text.slice(0,7000),article_count:posts.length,posts,external_links:external.slice(0,30),login_required:/log in to facebook|inicia sesión en facebook|log in or sign up/i.test(text)};
})()- On
/about, run:
(() => {const clean=v=>(v||'').replace(/\s+/g,' ').trim(),text=clean(document.body?.innerText||'');const links=[...document.querySelectorAll('a[href]')].map(a=>({href:a.href,text:clean(a.innerText)})).filter(x=>x.text||x.href);return {url:location.href,title:document.title,about_text:text.slice(0,12000),about_links:links.filter(x=>/about|contact|website|instagram|tiktok|whatsapp|email|phone/i.test(x.text+' '+x.href)).slice(0,80),login_required:/log in to facebook|inicia sesión en facebook|log in or sign up/i.test(text)}})()- On
/about_profile_transparency, run:
(() => {const text=(document.body?.innerText||'').replace(/\s+/g,' ').trim();return {url:location.href,title:document.title,transparency_text:text.slice(0,10000),login_required:/log in to facebook|inicia sesión en facebook|log in or sign up/i.test(text)}})()Only when Instagram verification is explicitly requested, use an Instagram URL supplied by the caller or extracted from visible Page links/About content. Navigate directly to
https://www.instagram.com/{instagram-handle}/and extract follower text fromog:description,description, or visible text. Preserve localized raw values such as12,3 mil; do not infer exact integers from abbreviations.Return all requested results together. Report the requested URL,
location.href, and canonical URL when Facebook redirects or canonicalizes the supplied handle. If a login wall, consent wall, challenge, or anti-bot page blocks extraction, return visible partial data and a reason; never authenticate or bypass it.
Site-Specific Gotchas
- Vanity handles are safe in the path only when supplied by the caller or resolved from Facebook search. Facebook may normalize casing, add a trailing slash, or redirect to another canonical vanity URL; always report final and canonical URLs.
- Facebook's logged-out Page DOM is progressively rendered. Wait 3–5 seconds and use only limited downward scrolling.
div[role="article"]is the useful post boundary, but shared-post cards can contain nested article-like content. Preserve outer article text and permalink rather than flattening nested articles.- Follower counts may be localized (
followers,seguidores,mil,K, orM) or absent. Preserve raw visible or metadata text and identify its source; do not calculate an exact count from an abbreviation. - Page-level
og:descriptionordescriptionmetadata may provide follower evidence when rendered text is sparse. /aboutand/about_profile_transparencyare separate routes and can expose different content; transparency may be empty or unavailable.- Visit a linked Instagram profile only when Instagram data is explicitly requested, and resolve its handle from a visible link or supplied URL rather than branding.
- Instagram may return a sparse shell, login prompt, challenge, or rate-limit page. Mark the result partial/blocked and do not attempt login or bypass measures.
- Do not use authenticated GraphQL endpoints, scrape credentials, or dismiss login prompts. This skill is public, read-only extraction only.
Expected Output
{
"requested_handle":"{page-handle}",
"requested_url":"https://www.facebook.com/{page-handle}",
"canonical_url":"{canonical URL or null}",
"final_url":"{rendered final URL}",
"followers":{"raw":"{raw follower text or null}","verification_source":"visible page text or og:description/description metadata"},
"page":{"title":"{title}","text_excerpt":"{visible text}","public_post_count_extracted":0,"posts":[],"external_links":[]},
"about":{"url":"https://www.facebook.com/{page-handle}/about","text":"{visible About text}","links":[]},
"profile_transparency":{"url":"https://www.facebook.com/{page-handle}/about_profile_transparency","text":"{visible transparency text}"},
"instagram":{"requested":false,"url":null,"canonical_url":null,"handle":null,"follower_text":null,"follower_count_raw":null,"verification_source":"meta[property=og:description] or meta[name=description]","partial":false},
"partial":false,
"partial_reason":null
}When Instagram verification is requested, set instagram.requested to true, include the resolved profile URL and raw follower text, and set partial:true if the profile is blocked or the count is unavailable.