Facebook Profile & Posts Scraper - Reactions & Metrics avatar

Facebook Profile & Posts Scraper - Reactions & Metrics

Under maintenance

Pricing

from $1.99 / 1,000 results

Go to Apify Store
Facebook Profile & Posts Scraper - Reactions & Metrics

Facebook Profile & Posts Scraper - Reactions & Metrics

Under maintenance

πŸ‘₯ Facebook Profile & Posts Scraper extracts timeline posts with the full 7-type reaction breakdown, comments, shares, media & author details. πŸ“Š Perfect for brand monitoring, sentiment & competitor analysis. πŸš€ No login needed. βœ…

Pricing

from $1.99 / 1,000 results

Rating

0.0

(0)

Developer

Scrapers Hub

Scrapers Hub

Maintained by Community

Actor stats

0

Bookmarked

4

Total users

4

Monthly active users

a day ago

Last modified

Share

πŸ‘₯ Facebook Profile & Posts Scraper β€” Timeline Posts, Reactions and Engagement Metrics

Facebook Profile & Posts Scraper collects posts from any public Facebook profile or page timeline and returns them with full engagement data β€” not just a reaction total, but the complete breakdown across all seven reaction types. Every post comes back with its text, media, author details, comment and share counts, and a Unix timestamp. Point it at a page URL, set how deep to scroll, and get a structured timeline you can chart, diff, or analyze. No Facebook login, Graph API app, or access token required.

πŸ€” What is Facebook Profile & Posts Scraper?

Facebook Profile & Posts Scraper is a timeline-extraction Actor that reads a public Facebook page or profile and returns its posts as structured rows. It scrolls the timeline to the depth you specify, capturing each post's content, attachments, and engagement metrics along the way.

Where Meta's Graph API restricts page insights to pages you administer, this reads the public timeline any visitor sees β€” which is what competitive analysis, brand monitoring, and social research actually need.

  • Full timeline extraction with configurable scroll depth
  • Complete reaction breakdown β€” like, love, care, haha, wow, sad, angry, individually
  • Post text in two forms β€” plain and rich
  • Media detection β€” images, video URLs, album previews
  • Attachment awareness β€” external link posts, shared posts, and attached events
  • No authentication β€” no Facebook account, app review, or Graph API token

❀️ The reaction breakdown is the point

Most Facebook scrapers give you a single engagement number. This one returns the full distribution:

{
"reactions_count": 5715,
"reactions": {
"like": 3129,
"love": 1366,
"care": 1200,
"sad": 16,
"haha": 2,
"wow": 1,
"angry": 1
}
}

That distribution carries information the total destroys. Two posts with 5,000 reactions each are not comparable if one is 90% like and the other is 40% angry β€” the first landed, the second caused a problem. angry share is the single most useful crisis-detection signal on Facebook, and it's invisible in a total. Likewise, a high love and care ratio marks content that built genuine affinity rather than mere acknowledgement.

Practical approach: compute each reaction as a proportion of reactions_count rather than using raw counts, so posts of different reach stay comparable. Watch angry proportion for reputational alerts and the love + care share as an affinity measure.

πŸ“ message versus message_rich

Post text arrives twice. message is the plain-text version, which is what you want for search, sentiment analysis, and anything text-processing. message_rich preserves the richer form including embedded entity markup β€” mentions and links as they appear in the post structure.

Use message by default. Reach for message_rich when you specifically need to know which accounts or pages a post tagged, since that relational information is stripped from the plain version.

πŸ“¦ What data can you get with Facebook Profile & Posts Scraper?

FieldTypeDescription
post_idstringFacebook post ID β€” the stable join key
typestringPost type, e.g. post
urlstringDirect link to the post (may be a Reel URL for video posts)
messagestringPlain post text
message_richstringPost text with entity markup preserved
timestampintegerPublish time as a Unix epoch second count
reactions_countintegerTotal reactions
reactionsobjectPer-type counts: like, love, care, haha, wow, sad, angry
comments_countintegerComments on the post
reshare_countintegerShares
authorobject{id, name, url, profile_picture_url}
author_titlestringAuthor subtitle, when present
imagestringImage URL, for image posts
videoobjectVideo details including a direct media URL
album_previewarrayPreview items for multi-image posts
external_urlstringTarget URL for link posts
attached_eventobjectEvent details, for event posts
attached_postobjectThe original post, for shares

Many of these are populated only for the post types they belong to β€” external_url on link posts, attached_post on shares, video on video posts. A null in those fields describes the post's type, not a failed extraction.

⏱️ Timestamps are Unix epoch integers

timestamp is an integer count of seconds, not an ISO date string:

from datetime import datetime, timezone
posted = datetime.fromtimestamp(row["timestamp"], tz=timezone.utc)

Convert on ingest. This also gives you post age, which is essential for fair engagement comparison β€” a post with 5,000 reactions after two days is outperforming one with 6,000 after three weeks.

πŸ†š How does Facebook Profile & Posts Scraper differ from the Graph API?

FeatureMeta Graph APIFacebook Profile & Posts Scraper
Access requirementDeveloper account, app review, page admin tokenNone β€” just a public page URL
Other pages' postsNot available without their authorizationAny public page or profile
Reaction breakdownAvailable for pages you administerIncluded for every post
Approval timeDays to weeks of app reviewImmediate
OutputNested, paginated Graph JSONFlat rows, CSV/JSON export

Use the Graph API to manage your own page, publish content, and read private insights. Use Facebook Profile & Posts Scraper for public timelines you don't administer.

πŸš€ How to scrape Facebook posts?

  1. Open the facebook-profile-posts-scraper Actor in Apify Console and click Try for free.
  2. Paste public page or profile URLs into startUrls.
  3. Set maxPages for how deep to scroll each timeline.
  4. Click Start β€” expect roughly 10 posts per minute, so budget generously.
  5. Export from the Dataset tab as JSON, CSV, or Excel.
{
"startUrls": [
{ "url": "https://www.facebook.com/humansofnewyork" }
],
"maxPages": 50
}

⏳ Run time and maxPages

This is the slowest Actor in the toolkit, and deliberately so β€” timelines are fetched page by page with realistic pacing. In testing, 50 posts took about 303 seconds, so plan on roughly ten posts per minute.

maxPages controls scroll depth per profile. It's a page count, not a post count, so the number of posts you get depends on how many each page yields. The practical guidance: start with a small maxPages to see the ratio for your target page, then scale up. On a multi-profile run, remember that depth applies per profile, so three profiles at maxPages: 50 is three times the work.

Set your run timeout well above your expected duration. A deep scrape of several profiles can comfortably exceed the default.

⬇️ Input

ParameterRequiredTypeDefaultDescription
startUrlsYesarrayHumans of New York examplePublic Facebook profile or page URLs
maxPagesNointeger50Maximum pages to scroll/fetch per profile
{
"startUrls": [
{ "url": "https://www.facebook.com/humansofnewyork" }
],
"maxPages": 50
}

Pitfall: only public pages and profiles work. Personal profiles with restricted privacy, private groups, and content limited to friends aren't accessible by any input setting. If a run returns nothing, verify the page loads for a logged-out visitor in a private browser window first.

Pitfall: maxPages is pages, not posts. There's no direct post cap, so cap it yourself by keeping maxPages modest and trimming after collection if you need an exact number.

Pitfall: run time scales with depth and profile count. Three profiles at maximum depth is a long run β€” raise your run timeout before starting rather than discovering the limit partway through.

⬆️ Output

One dataset row per post.

Scraped results

[
{
"post_id": "1608404244183892",
"type": "post",
"url": "https://www.facebook.com/reel/1564039698724000/",
"message": "I write him a letter every day.",
"message_rich": "I write him a letter every day.",
"timestamp": 1785526660,
"comments_count": 266,
"reactions_count": 5715,
"reshare_count": 107,
"reactions": {
"angry": 1, "care": 1200, "haha": 2,
"like": 3129, "love": 1366, "sad": 16, "wow": 1
},
"author": {
"id": "100050429952420",
"name": "Humans of New York",
"url": "https://www.facebook.com/humansofnewyork",
"profile_picture_url": "https://scontent-cdg6-1.xx.fbcdn.net/v/t39.30808-1/334611134.jpg"
},
"author_title": null,
"image": null,
"video": { "url": "https://video-cdg4-1.xx.fbcdn.net/o1/v/t2/f2/m412/AQNjU5xvlhrCERE.mp4" },
"external_url": null,
"attached_event": null,
"attached_post": null
}
]

Media URLs point at Facebook's CDN with signed, expiring parameters. They resolve immediately but stop working after some hours β€” download during or shortly after the run if you need the files.

πŸ’‘ How can I use the data from Facebook Profile & Posts Scraper?

  • Brand and comms teams: monitor the angry proportion across a page's recent posts as a reputational early-warning signal, well before it becomes a news cycle.
  • Social media managers: benchmark competitors' posting cadence from timestamp and their engagement mix from the reactions breakdown, then match format to what actually performs.
  • Content strategists: correlate message themes with the love + care share to find the content that builds affinity rather than just reach.
  • Market researchers: track how audiences react to campaigns and announcements across many pages using a consistent reaction distribution.
  • AI and LLM pipelines: feed post text plus reaction distributions to a model to classify content themes and explain what drives each type of response.

πŸ“ˆ How do you monitor a Facebook page over time?

Engagement on a post accumulates for days, so a single scrape is one point on a curve. Re-run Facebook Profile & Posts Scraper against the same pages on a schedule and join on post_id, which is stable.

Two things are worth tracking. New posts β€” the set difference between runs gives you a page's publishing activity without any manual checking. Engagement velocity β€” the change in reactions_count, comments_count, and reshare_count between runs, which distinguishes a post gaining 5,000 reactions in a day from one that took a month.

The reaction mix shifting over time on a single post is its own signal: angry share climbing after publication usually means a post is being shared into hostile audiences, and it's a genuinely useful alert. Because this Actor is slow, prefer a modest maxPages on a frequent schedule over deep scrapes run rarely β€” recent posts are where the movement is.

Apify Console's Schedule feature handles recurrence; a run-completion webhook pushes each batch into your dashboard.

πŸ”Œ Integrate Facebook Profile & Posts Scraper into your workflow

🐍 REST API with Python

import requests
from datetime import datetime, timezone
TOKEN = "YOUR_APIFY_TOKEN"
url = f"https://api.apify.com/v2/acts/scrapers-hub~facebook-profile-posts-scraper/run-sync-get-dataset-items?token={TOKEN}"
payload = {"startUrls": [{"url": "https://www.facebook.com/humansofnewyork"}], "maxPages": 10}
for post in requests.post(url, json=payload).json():
total = post["reactions_count"] or 1
angry_pct = post["reactions"].get("angry", 0) / total * 100
posted = datetime.fromtimestamp(post["timestamp"], tz=timezone.utc)
flag = " ⚠️ NEGATIVE" if angry_pct > 10 else ""
print(f"{posted:%Y-%m-%d} {total:>7,} reactions angry {angry_pct:4.1f}%{flag}")

πŸ€– MCP for AI agents

Register with Apify's Actors MCP Server β€” npx @apify/actors-mcp-server --tools scrapers-hub/facebook-profile-posts-scraper, or the hosted endpoint at https://mcp.apify.com β€” so an MCP client such as Claude Desktop or Claude.ai can read a page's recent posts and summarize how audiences responded.

⏰ Scheduled runs and webhooks

Use Apify Console's Schedule feature for recurring collection at modest depth, and a webhook to raise an alert when a post's angry proportion crosses your threshold.

πŸ’° Pricing

Billed per result β€” one charge per post row β€” plus Apify platform usage. Because runs are long (roughly ten posts per minute), platform compute is a meaningful share of total cost here, unlike the faster HTTP-only Actors. Keeping maxPages tight is the main lever on both cost and run time. Check the Actor's Apify Store page for current pricing.

Facebook Profile & Posts Scraper reads only public pages and profiles β€” content any logged-out visitor can see. Courts have found that scraping publicly available web data does not violate the U.S. Computer Fraud and Abuse Act (hiQ Labs, Inc. v. LinkedIn Corp., 9th Cir. 2019, reaffirmed 2022), while Meta's terms separately govern platform use.

Take the personal-data question seriously here. Author names, profile pictures, and post text about identifiable individuals are personal data under the GDPR even when published publicly, and posts from personal profiles carry more sensitivity than those from brand pages. Post content is copyrighted by its author. Prefer scraping organizational pages over individual profiles where your research allows it, and consult your legal team before bulk storage or commercial use.

❓ Frequently asked questions

Does it need a Facebook login?

No. It reads public pages and profiles directly β€” no account, app review, or Graph API token.

Can it scrape private profiles or groups?

No. Only content visible to a logged-out visitor is accessible. Check the page in a private browser window if a run returns nothing.

What's in the reaction breakdown?

All seven types individually β€” like, love, care, haha, wow, sad, and angry β€” alongside the reactions_count total. The distribution is far more informative than the total.

Why is timestamp a number?

It's a Unix epoch second count. Convert it with your language's standard datetime function.

What's the difference between message and message_rich?

message is plain text for analysis; message_rich preserves entity markup such as mentions and links. Use plain unless you need the tagged accounts.

Why are image, video, or external_url null?

Because that post doesn't have them. Fields populate according to post type β€” a text-only post has no media, a non-link post has no external_url.

How long does a run take?

Roughly ten posts per minute β€” 50 posts took about 303 seconds in testing. Raise your run timeout before deep scrapes.

Does maxPages limit the number of posts?

No, it limits pages scrolled per profile. Posts per page vary, so start small to gauge the ratio for your target, then scale.

How long do media URLs stay valid?

They're signed Facebook CDN links with expiring parameters β€” usable immediately, dead after some hours. Download during the run if you need them.

Can I get the comments themselves?

No, only comments_count. This Actor returns posts and their metrics, not comment threads.

  • Facebook Reels Scraper β€” detailed metadata for individual Reels found in a timeline
  • Facebook Groups Scraper β€” the same collection approach for group content
  • Instagram Profile Scraper β€” the Meta ecosystem's other major public surface
  • Merge, Dedup & Transform Datasets β€” deduplicate scheduled runs on post_id

πŸ’¬ Your feedback

Seeing a post type that doesn't parse, or reaction counts that look wrong? Report it through the Issues tab on this Actor's Apify Console page with the page URL and post link β€” Facebook varies its markup by post type, and specific examples make fixes possible.

Prefer email? Contact the team directly at scraperhubapi@gmail.com. Include the Actor name, the exact input you used, and the run ID so the issue can be reproduced and fixed quickly.