Quiz 2
Registry Synced

Data Collection from Social Media APIs

2220 words
11 min read

Reading compass

Now · 🎯 Learning Objectives

Data Collection from Social Media APIs

🎯 Learning Objectives

  • Understand how REST APIs work for social media data collection
  • Implement OAuth authentication for accessing platform data
  • Handle rate limits, pagination, and data formatting
  • Evaluate ethical and legal considerations of data collection
  • Apply sampling strategies for social media data

1. Social Media APIs: Overview

1.1 Intuition

Social media platforms like Twitter, Facebook, and Reddit hold vast amounts of public conversation data. But you can't just download everything — platforms provide APIs (Application Programming Interfaces) that let you request specific data programmatically. Think of an API like a restaurant menu: you can only order what's on the menu, you have to follow the restaurant's rules, and you can't take food from the kitchen directly. APIs enforce rules about how much data you can collect, how often you can make requests, and what types of data are available. Understanding these rules is essential for any serious social media researcher.

1.2 What is a REST API?

REST (Representational State Transfer) is the most common API architecture. Key concepts:
ConceptMeaningExample
EndpointA specific URL that returns datahttps://api.twitter.com/2/tweets
HTTP MethodWhat action to performGET (read), POST (create)
ParametersFilters and options?query=AI&max_results=10
HeadersAuthentication and metadataAuthorization: Bearer TOKEN
ResponseData returned (usually JSON){"data": [{"id": "123", "text": "..."}]}
How it works: (Diagram)

1.3 Common Social Media APIs

PlatformAPI NameKey EndpointsRate Limits
Twitter/XTwitter API v2/2/tweets, /2/users300 req/15 min (standard)
RedditReddit API/r/{subreddit}/hot60 req/min
FacebookGraph API/{page-id}/posts200 req/hr (per user)
InstagramBasic Display API/me/media200 req/hr
YouTubeData API v3/videos, /search10,000 units/day

2. Authentication: OAuth 2.0

2.1 Intuition

You can't just knock on a platform's door and ask for data — you need to prove who you are and what you're allowed to do. OAuth 2.0 is the standard protocol for this. It's like a hotel key card system: you check in at the front desk (get a token), and that token grants you access to specific areas (endpoints) for a limited time.

2.2 OAuth Flow

(Diagram)

2.3 Token Types

TokenLifetimePurpose
Bearer Token1-2 hoursSent with each request
Refresh TokenDays/monthsGet new bearer token without re-login
API KeyPermanentIdentifies your application

2.4 Python Example: Twitter API v2

python
import requests
import json
# Your credentials from developer portal
bearer_token = "AAAAAAAAAAAAAAAAAAAA..."
def create_headers(bearer_token):
    return {"Authorization": f"Bearer {bearer_token}"}
def connect_to_endpoint(url, headers):
    response = requests.get(url, headers=headers)
    if response.status_code != 200:
        raise Exception(f"Request returned {response.status_code}: {response.text}")
    return response.json()
# Search for recent tweets about "machine learning"
url = "https://api.twitter.com/2/tweets/search/recent"
params = {
    "query": "machine learning",
    "max_results": 10,
    "tweet.fields": "created_at,public_metrics"
}
headers = create_headers(bearer_token)
response = requests.get(url, headers=headers, params=params)
data = response.json()
for tweet in data['data']:
    print(f"{tweet['created_at']}: {tweet['text']}")
Output (abbreviated):
pseudo
2024-01-15T10:30:00Z: Just finished a great course on machine learning!
2024-01-15T10:28:00Z: Machine learning is transforming healthcare diagnostics...

3. Rate Limiting & Pagination

3.1 Rate Limiting

Platforms limit how many requests you can make to prevent abuse. Common strategies:
StrategyDescriptionExample
Fixed windowMax requests per time window300 requests per 15 minutes
Sliding windowRolling time window60 requests per minute
Token bucketTokens replenish at a fixed rate10 tokens/s, max 100
Response headers to watch for:
pseudo
x-rate-limit-limit: 300       # Max requests allowed
x-rate-limit-remaining: 284    # Requests remaining in window
x-rate-limit-reset: 1643123456 # Unix timestamp when window resets

3.2 Handling Rate Limits

python
import time
import requests
def rate_limited_request(url, headers, params, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers, params=params)
        if response.status_code == 429:  # Too Many Requests
            reset_time = int(response.headers.get('x-rate-limit-reset', 0))
            wait_time = max(reset_time - time.time(), 0) + 1
            print(f"Rate limited. Waiting {wait_time} seconds...")
            time.sleep(wait_time)
            continue
        if response.status_code == 200:
            remaining = response.headers.get('x-rate-limit-remaining', '?')
            print(f"Requests remaining: {remaining}")
            return response.json()
        print(f"Error {response.status_code}: {response.text}")
        return None
    print("Max retries exceeded")
    return None

3.3 Pagination

APIs rarely return all results at once — they paginate. Common pagination methods:
MethodHow it worksExample Parameter
Cursor-basedNext page tokennext_token=abc123
Page-basedPage numberpage=2
Offset-basedSkip N itemsoffset=100
Cursor-based pagination loop:
python
def collect_all_tweets(query, max_tweets=500):
    all_tweets = []
    next_token = None
    while len(all_tweets) < max_tweets:
        params = {
            "query": query,
            "max_results": 100,
            "tweet.fields": "created_at"
        }
        if next_token:
            params["next_token"] = next_token
        response = requests.get(url, headers=headers, params=params)
        data = response.json()
        if 'data' in data:
            all_tweets.extend(data['data'])
            print(f"Collected {len(all_tweets)} tweets so far")
        # Check for next page
        if 'meta' in data and 'next_token' in data['meta']:
            next_token = data['meta']['next_token']
        else:
            break
    return all_tweets[:max_tweets]

4. Data Formats & Processing

4.1 JSON Structure

Social media APIs typically return JSON. Here's what a tweet object looks like:
json
{
  "data": {
    "id": "1234567890",
    "text": "Machine learning is amazing! #AI",
    "created_at": "2024-01-15T10:30:00.000Z",
    "author_id": "98765",
    "public_metrics": {
      "retweet_count": 15,
      "reply_count": 3,
      "like_count": 142,
      "quote_count": 2
    },
    "entities": {
      "hashtags": [{"tag": "AI"}],
      "mentions": [{"username": "ml_expert"}]
    }
  },
  "includes": {
    "users": [
      {
        "id": "98765",
        "name": "ML Enthusiast",
        "username": "ml_fan",
        "public_metrics": {
          "followers_count": 2500,
          "following_count": 180,
          "tweet_count": 3400
        }
      }
    ]
  }
}

4.2 Converting to Structured Data

python
import pandas as pd
def tweets_to_dataframe(tweets_data):
    """Convert raw API response to a pandas DataFrame."""
    rows = []
    for tweet in tweets_data.get('data', []):
        row = {
            'tweet_id': tweet['id'],
            'text': tweet['text'],
            'created_at': tweet['created_at'],
            'retweets': tweet['public_metrics']['retweet_count'],
            'likes': tweet['public_metrics']['like_count'],
            'replies': tweet['public_metrics']['reply_count'],
        }
        rows.append(row)
    df = pd.DataFrame(rows)
    df['created_at'] = pd.to_datetime(df['created_at'])
    return df

5. Sampling Strategies

5.1 Why Sample?

Social media generates massive data — Twitter alone produces 500M+ tweets daily. You can't collect everything. Sampling strategies help you get representative data.

5.2 Sampling Methods

MethodDescriptionWhen to Use
Random samplingRandom selection of posts/usersGeneral population studies
Stratified samplingDivide by categories, sample eachComparing subgroups
Snowball samplingStart with seeds, follow connectionsNetwork analysis
Time-based samplingCollect during specific periodsEvent analysis
Keyword filteringCollect posts matching keywordsTopic-specific studies

5.3 Worked Example: Stratified Sampling

Suppose you want to compare political discourse across 5 countries. You decide to collect 2000 tweets per country.
python
countries = ['US', 'UK', 'IN', 'BR', 'JP']
tweets_per_country = 2000
collected = {}
for country in countries:
    query = f"politics lang:en place_country:{country}"
    collected[country] = collect_all_tweets(query, tweets_per_country)
    print(f"Collected {len(collected[country])} tweets from {country}")
Tracing Table:
StepActionCountryTweets CollectedCumulative
1Query US politicsUS20002000
2Query UK politicsUK20004000
3Query IN politicsIN20006000
4Query BR politicsBR20008000
5Query JP politicsJP200010000

6.1 Platform Terms of Service

Every platform has rules. Violating them can get your app banned or worse — legal action.
RuleWhy It Exists
No data resaleProtects user privacy
Rate limitsPrevents server overload
User consentRequired for private data
AttributionGive credit to platform
No scraping (some platforms)Explicit prohibition

6.2 GDPR & Data Privacy

If you're collecting data from EU users, GDPR applies:
RequirementWhat You Must Do
Lawful basisHave a legitimate reason
ConsentInform users and get consent
Data minimizationCollect only what you need
Right to deletionDelete user data on request
AnonymizationRemove personally identifiable info

6.3 Ethical Guidelines

(Diagram) Key ethical principles:
  1. Minimize harm: Don't expose sensitive information
  2. Be transparent: Disclose data collection methods
  3. Respect privacy: Anonymize, aggregate where possible
  4. Get consent: For non-public data
  5. Follow platform rules: Terms of service matter

7. Common Pitfalls

Pitfall 1: Ignoring Rate Limits

The mistake: Making too many requests too quickly, getting permanently banned. Why students make it: The first few requests work fine, so they assume there's no limit. Then suddenly everything breaks. How to catch it: Always log response headers. Watch for x-rate-limit-remaining approaching 0. Correct approach: Implement exponential backoff: wait 1s after first 429, 2s after second, 4s after third.

Pitfall 2: Storing API Keys in Code

The mistake: Hardcoding bearer tokens in Python files, then committing to GitHub. Why students make it: It's the quickest way to get something working. How to catch it: Before any git commit, check for suspicious strings. Use git-secrets or similar tools. Correct approach: Use environment variables or a .env file (never committed).
python
import os
from dotenv import load_dotenv
load_dotenv()
bearer_token = os.getenv("TWITTER_BEARER_TOKEN")

Pitfall 3: Not Handling Pagination

The mistake: Only collecting the first page of results (e.g., 10 tweets instead of 1000+). Why students make it: The first request works and returns data. It's easy to forget that more data exists. How to catch it: Check if the response has pagination tokens. Most APIs include next_token or next_page_url in responses. Correct approach: Always loop through pagination until no more pages or you have enough data.

8. Key Concepts Reference

ConceptDefinitionWhy It Matters
REST APIWeb API using HTTP methodsStandard for most social media platforms
OAuth 2.0Token-based authenticationSecure, delegated access
Bearer TokenAccess credential sent in headersProves authorization
Rate LimitMax requests per time windowPrevents abuse
PaginationSplitting results into pagesHandles large datasets
CursorPointer to next page of resultsEfficient pagination
JSONJavaScript Object NotationStandard data format
GDPREU data protection regulationLegal compliance requirement

9. 📝 Practice Questions

Q1: You make 300 API requests in 10 minutes. Rate limit is 300 per 15 minutes. How long must you wait before the next request?
Answer: The window resets 15 minutes after the first request in the window. Since you made 300 requests in 10 minutes, you've exhausted your quota. You need to wait until the 15-minute window from your first request expires. If your first request was at t=0, you can request again at t=15 minutes (5 more minutes of waiting). Q2: What's the difference between a bearer token and a refresh token?
Answer: A bearer token is short-lived (1-2 hours) and is sent with each API request to authenticate. A refresh token is long-lived (days to months) and is used to obtain new bearer tokens without requiring the user to re-authenticate. Refresh tokens are stored securely on the server side and never sent with API requests. Q3: An API returns paginated results with next_token. The first page contains 100 results. How many API calls are needed to collect 500 results?
Answer: Each call returns up to 100 results (max_results=100). To get 500 results: 500/100 = 5 calls. Call 1 gets page 1 with next_token; call 2 uses that token for page 2; and so on until call 5 completes. Total: 5 API calls. Q4: Why should you use environment variables instead of hardcoding API keys?
Answer: Hardcoding API keys in source code exposes them to anyone with access to the codebase. If committed to version control, they become permanently visible. Environment variables keep secrets out of code, can be set per-deployment (dev/staging/production), and reduce the risk of accidental exposure. Q5: A platform returns HTTP 429 after 50 requests. Your rate limit was supposed to be 300. What might be wrong?
Answer: Several possibilities: (1) The rate limit might be per-endpoint, not global — you might be hitting a different endpoint than you registered. (2) Your app might be in a lower tier (e.g., Essential vs. Academic). (3) The rate limit might reset on a different schedule than you assumed (e.g., per minute, not per 15 minutes). (4) You might have accidentally triggered a separate rate limit (e.g., per-user instead of per-app). Check the response headers for x-rate-limit-limit to see the actual limit. Q6: What is the difference between cursor-based and offset-based pagination?
Answer: Cursor-based pagination uses a token pointing to a specific item, guaranteeing no duplicates even if new data is added (stable cursor). Offset-based pagination skips N items, which can cause duplicates or missed items if data changes between pages. Cursor-based is preferred for real-time data (like social media feeds), while offset-based is simpler for static datasets. Q7: Under GDPR, what must you do if a user requests deletion of their data from your research dataset?
Answer: You must (1) identify all records containing their data across your systems, (2) delete those records or anonymize them so the user is no longer identifiable, (3) confirm deletion to the user within the required timeframe (usually 30 days), (4) ensure no backups retain the identifiable data. You should have a process for handling such requests before starting data collection. Q8: You're collecting tweets about a sensitive health topic. What ethical considerations apply?
Answer: (1) Anonymize user handles and IDs before analysis/storage. (2) Consider whether users expected their tweets to be public for this purpose. (3) Aggregate findings rather than quoting individual tweets. (4) Store data securely with access controls. (5) Have an IRB/ethics review if possible. (6) Be prepared for potential media attention or platform scrutiny. Q9: An API returns JSON with data and includes fields. What are includes for?
Answer: The includes field contains expanded objects referenced in the data field. For example, a tweet in data might have author_id: "123", and the actual user object with name, username, and metrics is in includes.users. This is called "side-loading" or "embedding" and reduces the number of API calls needed to get related data. It's more efficient than making separate calls for each user. Q10: Compare snowball sampling with stratified sampling for social media research.
Answer: Snowball sampling starts with initial "seed" users and follows their connections/mentions, making it ideal for network analysis and hard-to-reach populations. Stratified sampling divides the population into relevant categories (by country, language, etc.) and samples each proportionally, making it better for comparative studies. Snowball can introduce selection bias (connected users are similar), while stratified requires knowing the categories in advance.

10. 🔗 Cross-References

  • Week 1 - SNA Basics: Graph metrics from collected data
  • Week 3 - Text Analysis: Processing collected text data
  • Week 4 - Cyber Crime: API misuse patterns
  • BSCS4024 (Computer Networks): HTTP, REST API fundamentals Join Discord PreviousSNA BasicsNextText Analysis
Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.