Facebook Pages Data Extraction Guide 2025
Facebook Pages are goldmines of business intelligence. Competitor posts, engagement metrics, audience reactions—it's all there.
But Meta's API restrictions make accessing this data challenging. The Graph API requires app review, page tokens, and has limited data access for third-party developers.
Here's how to actually get Facebook Page data in 2025.
Need Facebook data? Check our Facebook API alternatives for easier options.
What Data Can You Extract?
Page Information
- Page name and category
- About/description
- Follower count
- Like count
- Location
- Contact info
- Website URL
Posts
- Post content (text, images, videos)
- Publication time
- Reactions (likes, love, haha, etc.)
- Comments count
- Share count
- Post type
Engagement Metrics
- Total reactions breakdown
- Comment volume over time
- Share patterns
- Post frequency
Method 1: Meta Graph API (Official)
Requirements:
- Facebook Developer Account
- App review for Page Public Content Access
- Page Access Token
// Official Graph API (if you have access)
const response = await fetch(
`https://graph.facebook.com/v18.0/${pageId}/posts?access_token=${accessToken}&fields=message,created_time,reactions.summary(total_count)`
);
const data = await response.json();
Limitations:
- App review can take weeks
- Limited to pages you own or have permission for
- Rate limits apply
- Many fields require additional permissions
Method 2: Third-Party APIs
For most developers, this is the practical solution:
async function getFacebookPage(pageUrl) {
const response = await fetch(
`https://api.sociavault.com/v1/scrape/facebook/page?url=${encodeURIComponent(pageUrl)}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
return response.json();
}
// Get page info
const page = await getFacebookPage('https://facebook.com/Nike');
console.log(page.data);
// {
// name: "Nike",
// category: "Sportswear Store",
// followers: 38000000,
// likes: 37500000,
// about: "Just Do It.",
// ...
// }
Get Page Posts
async function getPagePosts(pageUrl, count = 20) {
const response = await fetch(
`https://api.sociavault.com/v1/scrape/facebook/page/posts?url=${encodeURIComponent(pageUrl)}&count=${count}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
return response.json();
}
const posts = await getPagePosts('https://facebook.com/Nike', 50);
posts.data.forEach(post => {
console.log({
content: post.message,
reactions: post.reaction_count,
comments: post.comment_count,
shares: post.share_count,
posted: post.created_time
});
});
Get Post Comments
async function getPostComments(postUrl) {
const response = await fetch(
`https://api.sociavault.com/v1/scrape/facebook/post/comments?url=${encodeURIComponent(postUrl)}`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
return response.json();
}
Use Case: Competitor Analysis
Track Competitor Pages
const competitors = [
'https://facebook.com/nike',
'https://facebook.com/adidas',
'https://facebook.com/puma'
];
async function analyzeCompetitors() {
const analysis = [];
for (const competitor of competitors) {
const page = await getFacebookPage(competitor);
const posts = await getPagePosts(competitor, 30);
const avgEngagement = posts.data.reduce((sum, post) => {
return sum + post.reaction_count + post.comment_count + post.share_count;
}, 0) / posts.data.length;
const postFrequency = calculatePostFrequency(posts.data);
analysis.push({
name: page.data.name,
followers: page.data.followers,
avgEngagement,
postFrequency,
topPost: getTopPost(posts.data)
});
}
return analysis;
}
Compare Engagement Rates
function calculateEngagementRate(page, posts) {
const totalEngagement = posts.reduce((sum, post) => {
return sum + post.reaction_count + post.comment_count + post.share_count;
}, 0);
const avgEngagementPerPost = totalEngagement / posts.length;
const engagementRate = (avgEngagementPerPost / page.followers) * 100;
return engagementRate.toFixed(4);
}
Use Case: Content Research
Find Top Performing Content
async function findTopContent(pageUrl, days = 30) {
const posts = await getPagePosts(pageUrl, 100);
// Filter to date range
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
const recentPosts = posts.data.filter(p =>
new Date(p.created_time) > cutoff
);
// Sort by total engagement
const sorted = recentPosts.sort((a, b) => {
const engA = a.reaction_count + a.comment_count * 2 + a.share_count * 3;
const engB = b.reaction_count + b.comment_count * 2 + b.share_count * 3;
return engB - engA;
});
return sorted.slice(0, 10);
}
Analyze Content Types
async function analyzeContentTypes(pageUrl) {
const posts = await getPagePosts(pageUrl, 100);
const byType = {
text: [],
image: [],
video: [],
link: []
};
posts.data.forEach(post => {
byType[post.type || 'text'].push(post);
});
return Object.entries(byType).map(([type, posts]) => ({
type,
count: posts.length,
avgEngagement: average(posts.map(p =>
p.reaction_count + p.comment_count + p.share_count
))
}));
}
Use Case: Brand Monitoring
Track Brand Mentions
async function monitorBrandMentions(brandName) {
// Search Facebook for brand mentions
const response = await fetch(
`https://api.sociavault.com/v1/scrape/facebook/search?query=${encodeURIComponent(brandName)}&type=post`,
{ headers: { 'Authorization': `Bearer ${API_KEY}` } }
);
const { data } = await response.json();
return data.posts.map(post => ({
content: post.message,
page: post.page_name,
engagement: post.reaction_count,
sentiment: analyzeSentiment(post.message),
url: post.url
}));
}
Data Pipeline Example
const Database = require('better-sqlite3');
const db = new Database('facebook_data.db');
// Initialize schema
db.exec(`
CREATE TABLE IF NOT EXISTS pages (
id INTEGER PRIMARY KEY,
url TEXT UNIQUE,
name TEXT,
followers INTEGER,
updated_at DATETIME
);
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY,
page_id INTEGER,
post_id TEXT UNIQUE,
message TEXT,
reactions INTEGER,
comments INTEGER,
shares INTEGER,
created_at DATETIME,
FOREIGN KEY (page_id) REFERENCES pages(id)
);
`);
async function syncPage(pageUrl) {
// Get page data
const page = await getFacebookPage(pageUrl);
// Upsert page
db.prepare(`
INSERT INTO pages (url, name, followers, updated_at)
VALUES (?, ?, ?, datetime('now'))
ON CONFLICT(url) DO UPDATE SET
followers = excluded.followers,
updated_at = excluded.updated_at
`).run(pageUrl, page.data.name, page.data.followers);
const pageRow = db.prepare('SELECT id FROM pages WHERE url = ?').get(pageUrl);
// Get posts
const posts = await getPagePosts(pageUrl, 50);
// Insert posts
const insertPost = db.prepare(`
INSERT OR REPLACE INTO posts
(page_id, post_id, message, reactions, comments, shares, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
`);
for (const post of posts.data) {
insertPost.run(
pageRow.id,
post.post_id,
post.message,
post.reaction_count,
post.comment_count,
post.share_count,
post.created_time
);
}
}
Best Practices
1. Respect Rate Limits
async function batchFetch(urls, delayMs = 1000) {
const results = [];
for (const url of urls) {
const data = await getFacebookPage(url);
results.push(data);
await new Promise(r => setTimeout(r, delayMs));
}
return results;
}
2. Cache Data
const pageCache = new Map();
async function getCachedPage(url) {
if (pageCache.has(url)) {
const cached = pageCache.get(url);
if (Date.now() - cached.time < 3600000) { // 1 hour
return cached.data;
}
}
const data = await getFacebookPage(url);
pageCache.set(url, { data, time: Date.now() });
return data;
}
3. Handle Private Pages
async function safeGetPage(url) {
try {
const data = await getFacebookPage(url);
return { success: true, data };
} catch (error) {
if (error.message.includes('private')) {
return { success: false, reason: 'private' };
}
throw error;
}
}
Comparison: Official API vs Third-Party
| Feature | Graph API | Third-Party API |
|---|---|---|
| Setup time | Weeks (app review) | Minutes |
| Page access | Own pages only | Any public page |
| Historical data | Limited | Available |
| Rate limits | Strict | Flexible |
| Cost | Free (limited) | Pay per request |
Ready to extract Facebook Page data?
Get started with 50 free credits at SociaVault.
Related:
Found this helpful?
Share it with others who might benefit
Ready to Try SociaVault?
Start extracting social media data with our powerful API. No credit card required.