Facebook Page Insights and Post Analytics Extractor

Automated Data Retrieval and Analysis for Comprehensive Facebook Page Performance Insights

Category: Social Media Analytics, Data Engineering, API Integration, Python Development
Tools & Technologies: Python, Facebook Graph API, `requests`, `json`, Data Processing, API Automation, Visual Studio Code, Google Colab

Status: Completed


Introduction

This project demonstrates the robust extraction and processing of data directly from the Facebook Graph API to provide detailed insights into Facebook Page performance and individual post engagement. Developed using Python, the system fetches key metrics such as impressions, engagements, fan growth, and reactions for the page, as well as in-depth analytics for specific posts, including reach, clicks, and engagement types. The output is structured into clean, summarized data and raw API responses, suitable for direct analysis, reporting, or integration into larger data dashboards. This solution addresses the need for automated social media performance tracking and analysis, offering a clear view of content effectiveness and audience interaction.


Aim and Objectives

Aim:
To create an automated system for extracting and analyzing Facebook Page insights and post-level performance data using the Facebook Graph API.

Objectives:

  1. Fetch key page-level performance metrics (e.g., impressions, engagements, fans).
  2. Retrieve a list of recent posts from a specified Facebook Page.
  3. Gather detailed, post-specific analytics, gracefully handling missing metrics for older posts.
  4. Structure and format the data into both raw API responses and clean, summarized outputs.
  5. Save the processed data into JSON files for archival and further analysis.
  6. Ensure robust error handling for API requests and data processing.

Features & Deliverables

  • Page-Level Insights: Retrieves aggregated data like impressions, post engagements, and fan counts over specified periods.
  • Post-Level Analytics: Extracts detailed metrics for individual posts, including reach, clicks, reactions, and engagement users.
  • Comprehensive Data Structuring: Organizes data into a clean `page_level_summary` and a detailed `comprehensive_post_analytics` list.
  • Raw Data Archival: Saves the full, unprocessed API responses for `raw_page_insights` and `page_posts_list`.
  • Automated Reporting: Generates `facebook_analytics.json` (clean data) and `facebook_analytics_all_data.json` (raw data).
  • Graceful Error Handling: Manages API errors and gracefully handles metrics that might not be available for all posts.

Code Implementation

The project is built using a Python script that interacts with the Facebook Graph API. It utilizes the `requests` library for HTTP requests and `json` for data handling. The code is structured into a class `FacebookGraphAPI` to encapsulate the logic for fetching different types of data.

View Python Script (Facebook Analytics)

import requests
import json
from datetime import datetime

class FacebookGraphAPI:
    def __init__(self, page_id, page_access_token):
        self.page_id = page_id
        self.page_access_token = page_access_token
        self.base_url = "https://graph.facebook.com/v19.0"

    def get_page_insights_raw(self, period='days_28'):
        print("\\n--- Fetching Raw Facebook Page-Level Insights ---")
        metrics = 'page_impressions,page_post_engagements,page_fans,page_actions_post_reactions_total'
        url = f"{self.base_url}/{self.page_id}/insights"
        params = {'metric': metrics, 'period': period, 'access_token': self.page_access_token}
        return self._handle_response(requests.get(url, params=params))

    def get_page_posts(self, limit=10):
        print("\\n--- Fetching Recent Facebook Page Posts ---")
        url = f"{self.base_url}/{self.page_id}/posts"
        params = {'fields': 'id,message,created_time,permalink_url', 'limit': limit, 'access_token': self.page_access_token}
        return self._handle_response(requests.get(url, params=params))

    def get_post_insights(self, post_id):
        all_possible_metrics = [
            'post_impressions', 'post_impressions_unique', 'post_engaged_users', 'post_clicks',
            'post_reactions_like_total', 'post_reactions_love_total', 'post_reactions_wow_total',
            'post_reactions_haha_total', 'post_reactions_sad_total', 'post_reactions_angry_total'
        ]
        formatted_insights = {}
        for metric in all_possible_metrics:
            url = f"{self.base_url}/{post_id}/insights"
            params = {'metric': metric, 'period': 'lifetime', 'access_token': self.page_access_token}
            response = requests.get(url, params=params)
            insight_data = self._handle_response(response, supress_error_print=True)
            if insight_data and 'data' in insight_data and insight_data['data']:
                value = insight_data['data'][0].get('values', [{}])[0].get('value', 0)
                formatted_insights[metric] = value
            else:
                formatted_insights[metric] = 0
        return formatted_insights

    def get_comprehensive_post_analytics(self, post_data):
        print(f"--- Analyzing Post ID: {post_data['id']} ---")
        insights = self.get_post_insights(post_data['id'])
        return {
            "post_details": post_data,
            "insights": insights,
            "summary": {
                "impressions": insights.get('post_impressions', 0),
                "reach": insights.get('post_impressions_unique', 0),
                "engaged_users": insights.get('post_engaged_users', 0),
                "clicks": insights.get('post_clicks', 0),
                "total_likes": insights.get('post_reactions_like_total', 0)
            }
        }

    def _handle_response(self, response, supress_error_print=False):
        if response.status_code == 200:
            return response.json()
        if not supress_error_print:
            try:
                error_data = response.json()
                print(f"API Error ({response.status_code}): {error_data.get('error', {}).get('message', 'No error message provided.')}")
            except json.JSONDecodeError:
                print(f"API Error ({response.status_code}): {response.text}")
        return None

def setup_api():
    FACEBOOK_PAGE_ID = "YOUR_FACEBOOK_PAGE_ID" # Replace with your Page ID
    FACEBOOK_PAGE_ACCESS_TOKEN = "YOUR_FACEBOOK_PAGE_ACCESS_TOKEN" # Replace with your Page Access Token
    if "YOUR" in FACEBOOK_PAGE_ID or "YOUR" in FACEBOOK_PAGE_ACCESS_TOKEN:
        print("!!! ERROR: Facebook credentials are not set in setup_api() !!!")
        return None
    return FacebookGraphAPI(FACEBOOK_PAGE_ID, FACEBOOK_PAGE_ACCESS_TOKEN)

if __name__ == "__main__":
    print("\\n" + "="*25 + " FACEBOOK ANALYTICS " + "="*26)
    fb_api = setup_api()
    if fb_api:
        raw_page_insights = fb_api.get_page_insights_raw()
        page_posts = fb_api.get_page_posts(limit=3)
        comprehensive_analytics = []
        if page_posts and 'data' in page_posts:
            print("\\n--- Fetching Comprehensive Insights for each Facebook Post ---")
            for post in page_posts['data']:
                analytics = fb_api.get_comprehensive_post_analytics(post)
                if analytics:
                    comprehensive_analytics.append(analytics)
        clean_page_insights = {}
        if raw_page_insights and 'data' in raw_page_insights:
            for metric in raw_page_insights['data']:
                metric_name = metric['name']
                metric_value = metric.get('values', [{}])[-1].get('value', 0)
                clean_page_insights[metric_name] = metric_value
        print("\\n--- Clean Page-Level Summary ---")
        print(json.dumps(clean_page_insights, indent=4))
        print("\\n--- Comprehensive Post Analytics ---")
        print(json.dumps(comprehensive_analytics, indent=4))
        clean_data_to_save = {
            "page_level_summary": clean_page_insights,
            "comprehensive_post_analytics": comprehensive_analytics
        }
        with open("facebook_analytics.json", 'w') as f:
            json.dump(clean_data_to_save, f, indent=4)
        print("\\n==================================================")
        print("SUCCESS: Clean summary saved to facebook_analytics.json")
        all_raw_data_to_save = {
            "raw_page_insights": raw_page_insights,
            "page_posts_list": page_posts
        }
        with open("facebook_analytics_all_data.json", 'w') as f:
            json.dump(all_raw_data_to_save, f, indent=4)
        print("SUCCESS: Full raw data saved to facebook_analytics_all_data.json")
        print("==================================================")
                        

Results & Impact

  • Automated Data Collection: Successfully automated the retrieval of key Facebook Page performance metrics and detailed post analytics.
  • Structured Insights: Provided organized data for easy consumption, enabling quick analysis of content effectiveness and audience engagement.
  • Data Archival: Ensured a reliable backup of raw API data for historical reference and potential deeper dives.
  • Demonstrated API Proficiency: Showcased the ability to interact with complex APIs, parse responses, and handle potential data inconsistencies.

Console Output Preview (Facebook Analytics)


========================= FACEBOOK ANALYTICS ==========================

--- Fetching Raw Facebook Page-Level Insights ---

--- Fetching Recent Facebook Page Posts ---

--- Fetching Comprehensive Insights for each Facebook Post ---
--- Analyzing Post ID: 654529707751538_122093590958929499 ---
--- Analyzing Post ID: 654529707751538_122093348108929499 ---

--- Clean Page-Level Summary ---
{
    "page_impressions": 41,
    "page_post_engagements": 14,
    "page_actions_post_reactions_total": {
        "like": 5
    }
}

--- Comprehensive Post Analytics ---
[
    {
        "post_details": {
            "id": "654529707751538_122093590958929499",
            "message": "Success. An unlimited solution to failure.",
            "created_time": "2025-06-22T10:44:19+0000",
            "permalink_url": "https://www.facebook.com/122094368966929499/posts/122093590958929499"
        },
        "insights": {
            "post_impressions": 3,
            "post_impressions_unique": 3,
            "post_engaged_users": 0,
            "post_clicks": 2,
            "post_reactions_like_total": 1,
            "post_reactions_love_total": 0,
            "post_reactions_wow_total": 0,
            "post_reactions_haha_total": 0,
            "post_reactions_sad_total": 0,
            "post_reactions_angry_total": 0
        },
        "summary": {
            "impressions": 3,
            "reach": 3,
            "engaged_users": 0,
            "clicks": 2,
            "total_likes": 1
        }
    },
    {
        "post_details": {
            "id": "654529707751538_122093348108929499",
            "message": "fruits - a good diet for the body.",
            "created_time": "2025-06-21T22:44:04+0000",
            "permalink_url": "https://www.facebook.com/122094368966929499/posts/122093348108929499"
        },
        "insights": {
            "post_impressions": 3,
            "post_impressions_unique": 3,
            "post_engaged_users": 0,
            "post_clicks": 1,
            "post_reactions_like_total": 3,
            "post_reactions_love_total": 0,
            "post_reactions_wow_total": 0,
            "post_reactions_haha_total": 0,
            "post_reactions_sad_total": 0,
            "post_reactions_angry_total": 0
        },
        "summary": {
            "impressions": 3,
            "reach": 3,
            "engaged_users": 0,
            "clicks": 1,
            "total_likes": 3
        }
    }
]

==================================================
SUCCESS: Clean summary saved to facebook_analytics.json
SUCCESS: Full raw data saved to facebook_analytics_all_data.json
==================================================
                            


Process / Methodology

API Interaction and Data Retrieval

  • Facebook Graph API: Utilized the Graph API (v19.0) to connect with Facebook's data.
  • Authentication: Employed a Page Access Token for secure access to Page insights and posts.
  • Page Insights: Fetched key metrics like 'page_impressions', 'page_post_engagements', 'page_fans', and 'page_actions_post_reactions_total' using the `/insights` endpoint with specified periods (e.g., 'days_28').
  • Post Retrieval: Queried the `/posts` endpoint to get a list of recent posts, including their ID, message, creation time, and permalink.
  • Post-Specific Insights: For each post, iterated through a comprehensive list of potential metrics (e.g., 'post_impressions', 'post_clicks', 'post_reactions_like_total') via the post's `/insights` endpoint, using 'lifetime' for cumulative values.

Data Processing and Structuring

  • Comprehensive Post Analytics: Created a structured dictionary for each post containing its details and a sub-dictionary of its fetched insights.
  • Summary Generation: Extracted key performance indicators (impressions, reach, engaged users, clicks, total likes) into a concise 'summary' object for each post.
  • Page-Level Summary: Processed the raw page insights to create a clean key-value pair dictionary of metrics and their latest values.
  • Error Handling: Implemented a `_handle_response` method to manage API errors (status codes other than 200) and gracefully return `None` or print error messages, while also handling cases where specific metrics are unavailable for a post by defaulting to 0.

Output Generation

  • Clean Data Output: Generated `facebook_analytics.json` containing the `page_level_summary` and `comprehensive_post_analytics`.
  • Raw Data Archival: Created `facebook_analytics_all_data.json` to store the complete, unprocessed data returned by the API for both page insights and the post list, preserving the original API structure.

Challenges & Solutions

  • Challenge: Handling API rate limits and potential throttling.
    Solution: Implemented basic error handling for non-200 status codes. For production, advanced retry mechanisms with exponential backoff would be necessary.
  • Challenge: Missing metrics for certain posts (e.g., older posts, specific content types).
    Solution: The `get_post_insights` method gracefully defaults to `0` for any metric not returned by the API for a given post, ensuring a complete data structure.
  • Challenge: Understanding and correctly querying the vast array of available Facebook Graph API metrics.
    Solution: Careful study of the Facebook Graph API documentation and iterative testing to identify the most relevant metrics for page and post performance.

What I Learned

  • Deepened understanding of the Facebook Graph API and its capabilities for social media analytics.
  • Practiced robust Python scripting for API integration, data parsing, and file management.
  • Learned to structure data effectively for both raw archival and simplified reporting.
  • Gained experience in handling API-specific error conditions and data inconsistencies.

Demonstration / Access


Future Enhancements

  1. Implement a scheduler for automated daily/weekly data fetching.
  2. Integrate with a dashboarding tool (e.g., Tableau, Power BI, custom web app) for visual representation of insights.
  3. Add support for fetching comments and reactions data at a more granular level.
  4. Expand functionality to include other social media platforms.

Thank You for Exploring My Facebook Analytics Project

I appreciate you taking the time to review my work on extracting valuable insights from the Facebook Graph API. This project highlights my commitment to leveraging data for informed decision-making in social media marketing and performance analysis.

For inquiries or potential collaborations, please connect through my Contact section. I welcome your feedback and discussions.

Best regards,
Damilare Lekan Adekeye