Instaloader
Overview
섹션 제목: “Overview”Instaloader is a Python tool for downloading Instagram profiles, posts, stories, and reels while preserving metadata. It’s designed for OSINT research, academic purposes, and understanding Instagram’s data structures. The tool operates through public Instagram APIs and respects terms of service when used appropriately.
Installation
섹션 제목: “Installation”Linux (Debian/Ubuntu)
섹션 제목: “Linux (Debian/Ubuntu)”sudo apt-get update
sudo apt-get install python3 python3-pip
pip3 install instaloader
macOS
섹션 제목: “macOS”brew install python3
pip3 install instaloader
Windows
섹션 제목: “Windows”# Python 3.6+ required
python -m pip install instaloader
Docker
섹션 제목: “Docker”FROM python:3.11-slim
RUN pip install instaloader
ENTRYPOINT ["instaloader"]
Build from Source
섹션 제목: “Build from Source”git clone https://github.com/instaloader/instaloader.git
cd instaloader
python3 -m pip install -e .
Verify Installation
섹션 제목: “Verify Installation”instaloader --version
instaloader -h
Basic Usage
섹션 제목: “Basic Usage”| Command | Description |
|---|---|
instaloader profile_name | Download profile |
instaloader --login username | Login with username |
instaloader --stories profile_name | Download stories |
instaloader --igtv profile_name | Download IGTV/reels |
instaloader "#hashtag" | Download hashtag posts |
instaloader @username | Download profile by handle |
Command-Line Options
섹션 제목: “Command-Line Options”Profile Options
섹션 제목: “Profile Options”--profile-pic Download profile picture
--stories Download stories
--highlights Download story highlights
--tagged Download tagged photos
--igtv Download IGTV/reels
--no-videos Skip video files
--no-captions Skip captions
--no-metadata-json Don't save JSON metadata
Authentication
섹션 제목: “Authentication”--login USERNAME Login with username
--password PASSWORD Provide password (not recommended)
--session FILE Use saved session file
--load-cookies FILE Load cookies from file
--save-cookies FILE Save cookies for reuse
Download Filtering
섹션 제목: “Download Filtering”-C, --count Maximum posts to download
--latest-stamps FILE Only posts newer than timestamp
--post-filter Python expression for filtering
--skip-posts Skip posts
--geotags Download geotag data
Output Options
섹션 제목: “Output Options”-d, --dirname Custom output directory
-f, --filename Custom filename format
--flat-out Flat directory structure
--no-profile-pic Skip profile picture
--metadata-local Store metadata locally
--quiet Minimal output
--verbose Verbose output
Authentication
섹션 제목: “Authentication”Session Management
섹션 제목: “Session Management”First-Time Login
섹션 제목: “First-Time Login”# Interactive login with browser
instaloader --login username
# Follow prompts:
# 1. Enter password
# 2. Complete 2FA if prompted
# 3. Session automatically saved
Reuse Saved Session
섹션 제목: “Reuse Saved Session”# Session stored in config directory
# ~/.local/share/instaloader/
# or ~/.config/instaloader/
# Login returns session file
instaloader --login username
# Subsequent runs use cached session
instaloader username
Save Session Explicitly
섹션 제목: “Save Session Explicitly”# Save session for later use
instaloader --login username --save-session session.json
# Load specific session
instaloader --session session.json profile_name
Cookie-Based Authentication
섹션 제목: “Cookie-Based Authentication”# Export cookies from browser
# Use browser extension (e.g., EditThisCookie)
# Save as cookies.txt
# Use exported cookies
instaloader --load-cookies cookies.txt profile_name
Profile Analysis
섹션 제목: “Profile Analysis”Download Complete Profile
섹션 제목: “Download Complete Profile”Basic Profile Download
섹션 제목: “Basic Profile Download”# Download all public posts
instaloader profile_name
# Output structure:
# profile_name/
# ├── 2024-01-15_ABC123_0.jpg
# ├── 2024-01-15_ABC123_0.txt (caption)
# ├── 2024-01-15_ABC123_0.json (metadata)
# └── profile.json (profile info)
Profile with Metadata
섹션 제목: “Profile with Metadata”# Download including all metadata
instaloader --profile-pic --stories \
--no-captions profile_name
# profile.json contains:
# - username
# - full_name
# - biography
# - follower_count
# - following_count
# - is_private
# - business_category_name
# - external_url
# - contact_email
Extract Profile Information
섹션 제목: “Extract Profile Information”Profile Metadata Analysis
섹션 제목: “Profile Metadata Analysis”#!/usr/bin/env python3
import json
# Load profile metadata
with open('profile_name/profile.json', 'r') as f:
profile = json.load(f)
# Extract key information
print(f"Username: {profile['username']}")
print(f"Full Name: {profile['full_name']}")
print(f"Biography: {profile['biography']}")
print(f"Followers: {profile['follower_count']}")
print(f"Following: {profile['following_count']}")
print(f"Posts: {profile['edge_owner_to_timeline_by_timeline']['edges'].__len__()}")
print(f"Website: {profile['external_url']}")
print(f"Contact: {profile['contact_email']}")
print(f"Business Category: {profile['business_category_name']}")
Download Stories
섹션 제목: “Download Stories”Story Collection
섹션 제목: “Story Collection”# Download all stories
instaloader --stories profile_name
# With metadata
instaloader --stories --metadata-local profile_name
# Only latest stories
instaloader --stories --count 10 profile_name
# Stories saved with timestamps
# profile_name/stories/
# ├── 2024-01-15_120000_story.jpg
# ├── 2024-01-15_120000_story.json
Story Timestamp Analysis
섹션 제목: “Story Timestamp Analysis”#!/usr/bin/env python3
import os
import json
from datetime import datetime
story_dir = "profile_name/stories"
for filename in sorted(os.listdir(story_dir)):
if filename.endswith('.json'):
with open(os.path.join(story_dir, filename)) as f:
data = json.load(f)
# Extract timestamp
taken_at = data.get('taken_at_timestamp', 0)
timestamp = datetime.fromtimestamp(taken_at)
print(f"{filename}: {timestamp}")
Download Highlights
섹션 제목: “Download Highlights”Story Highlights Preservation
섹션 제목: “Story Highlights Preservation”# Download story highlights
instaloader --highlights profile_name
# Output: profile_name/stories/highlight_name/
# Contains:
# - Highlight cover image
# - All stories in highlight
# - Metadata files
# Access saved highlights
ls -la profile_name/stories/highlight_*
Hashtag and Location Analysis
섹션 제목: “Hashtag and Location Analysis”Hashtag Research
섹션 제목: “Hashtag Research”Download Hashtag Posts
섹션 제목: “Download Hashtag Posts”# Download posts with hashtag
instaloader "#hashtag"
# Limit results
instaloader "#hashtag" --count 100
# Filter by date
instaloader "#hashtag" \
--post-filter "date > datetime(2024,1,1)"
Hashtag Analysis Script
섹션 제목: “Hashtag Analysis Script”#!/usr/bin/env python3
import json
import os
from collections import defaultdict
hashtag = "hashtag"
hashtag_dir = hashtag.replace("#", "")
# Analyze posts
engagement = defaultdict(int)
authors = set()
for filename in os.listdir(hashtag_dir):
if filename.endswith('.json'):
with open(os.path.join(hashtag_dir, filename)) as f:
post = json.load(f)
authors.add(post['owner']['username'])
engagement[post['owner']['username']] += (
post['edge_liked_by']['edge_likedby_count'] +
post['edge_media_to_caption']['edges'].__len__()
)
# Print top contributors
print(f"Total unique authors: {len(authors)}")
print("\nTop 10 contributors:")
for author, score in sorted(engagement.items(),
key=lambda x: x[1],
reverse=True)[:10]:
print(f"{author}: {score} engagements")
Location Research
섹션 제목: “Location Research”Download Location Posts
섹션 제목: “Download Location Posts”# Note: Instaloader has limited location support
# Alternative: Manual location lookup
# Find posts from location
# Typically requires manual browsing or API
# Workaround: Download posts mentioning location
instaloader -C 100 \
--post-filter "location == 'Location Name'"
Advanced Workflows
섹션 제목: “Advanced Workflows”OSINT Intelligence Gathering
섹션 제목: “OSINT Intelligence Gathering”Complete Profile Intelligence
섹션 제목: “Complete Profile Intelligence”#!/bin/bash
TARGET="target_username"
OUTPUT_DIR="osint_results"
mkdir -p "$OUTPUT_DIR"
echo "[*] Gathering OSINT on $TARGET"
# 1. Download profile
echo "[*] Downloading profile..."
instaloader --login your_username --profile-pic \
--stories "$TARGET" -d "$OUTPUT_DIR"
# 2. Extract metadata
echo "[*] Extracting metadata..."
python3 << 'EOF'
import json
import os
profile_file = f"$OUTPUT_DIR/$TARGET/profile.json"
if os.path.exists(profile_file):
with open(profile_file) as f:
profile = json.load(f)
intel = {
'username': profile['username'],
'full_name': profile['full_name'],
'bio': profile['biography'],
'followers': profile['follower_count'],
'following': profile['following_count'],
'website': profile['external_url'],
'email': profile['contact_email'],
'business': profile['business_category_name']
}
with open(f"$OUTPUT_DIR/intelligence.json", 'w') as out:
json.dump(intel, out, indent=2)
print("[+] Intelligence extracted")
EOF
echo "[*] OSINT complete. Results in $OUTPUT_DIR/"
Social Network Analysis
섹션 제목: “Social Network Analysis”#!/usr/bin/env python3
import json
import os
from collections import Counter
def analyze_social_network(profile_dir):
"""Analyze follower/following relationships"""
profile_file = os.path.join(profile_dir, 'profile.json')
with open(profile_file) as f:
profile = json.load(f)
# Extract relationships
followers = profile['follower_count']
following = profile['following_count']
print(f"Profile: {profile['username']}")
print(f"Followers: {followers}")
print(f"Following: {following}")
print(f"Engagement Ratio: {followers / max(following, 1):.2f}")
# Analyze posts
posts = profile['edge_owner_to_timeline_by_timeline']['edges']
engagement_scores = []
for post in posts[:20]: # Last 20 posts
node = post['node']
likes = node['edge_liked_by']['count']
comments = node['edge_media_to_caption']['edges'].__len__()
engagement = likes + (comments * 2) # Weight comments higher
engagement_scores.append(engagement)
avg_engagement = sum(engagement_scores) / len(engagement_scores)
print(f"\nAverage engagement (last 20): {avg_engagement:.0f}")
print(f"Engagement rate: {(avg_engagement / followers * 100):.2f}%")
# Usage
analyze_social_network('target_username')
Content Analysis
섹션 제목: “Content Analysis”Post Metadata Extraction
섹션 제목: “Post Metadata Extraction”#!/usr/bin/env python3
import json
import os
from datetime import datetime
from collections import defaultdict
def analyze_posts(profile_dir):
"""Analyze post patterns and content"""
posts_dir = os.path.join(profile_dir)
post_types = defaultdict(int)
posting_hours = defaultdict(int)
engagement_by_type = defaultdict(list)
for filename in os.listdir(posts_dir):
if not filename.endswith('.json'):
continue
filepath = os.path.join(posts_dir, filename)
with open(filepath) as f:
try:
post = json.load(f)
except:
continue
# Determine post type
is_video = post.get('is_video', False)
post_type = 'video' if is_video else 'image'
post_types[post_type] += 1
# Extract timestamp
timestamp = datetime.fromtimestamp(post['taken_at_timestamp'])
posting_hours[timestamp.hour] += 1
# Engagement metrics
likes = post.get('edge_liked_by', {}).get('count', 0)
comments = post.get('edge_media_to_comment', {}).get('count', 0)
engagement_by_type[post_type].append(likes + comments)
# Print analysis
print(f"Content breakdown:")
for post_type, count in post_types.items():
print(f" {post_type}: {count}")
print(f"\nPosting frequency by hour (UTC):")
for hour, count in sorted(posting_hours.items()):
print(f" {hour:02d}:00 - {hour:02d}:59: {count}")
print(f"\nAverage engagement by type:")
for post_type, scores in engagement_by_type.items():
avg = sum(scores) / len(scores) if scores else 0
print(f" {post_type}: {avg:.0f}")
# Usage
analyze_posts('target_username')
Video and Media Download
섹션 제목: “Video and Media Download”Download Video Content
섹션 제목: “Download Video Content”# Download IGTV/Reels
instaloader --igtv target_username
# Download all media including videos
instaloader --no-captions target_username
# Video files saved as MP4
# With metadata in JSON files
Media Organization
섹션 제목: “Media Organization”#!/bin/bash
# Organize downloads by type
SOURCE="target_username"
OUTPUT="organized_media"
mkdir -p "$OUTPUT"/{photos,videos,stories,metadata}
# Separate by file type
for file in "$SOURCE"/*.jpg; do
[ -f "$file" ] && cp "$file" "$OUTPUT/photos/"
done
for file in "$SOURCE"/*.mp4; do
[ -f "$file" ] && cp "$file" "$OUTPUT/videos/"
done
for file in "$SOURCE"/*.json; do
[ -f "$file" ] && cp "$file" "$OUTPUT/metadata/"
done
# Stories
if [ -d "$SOURCE/stories" ]; then
cp -r "$SOURCE/stories" "$OUTPUT/stories"
fi
echo "[+] Media organized in $OUTPUT/"
Rate Limiting and Ethics
섹션 제목: “Rate Limiting and Ethics”Responsible Usage
섹션 제목: “Responsible Usage”Request Rate Limiting
섹션 제목: “Request Rate Limiting”# Add delay between requests
instaloader --sleep-after-login 30 username
# Throttle requests
instaloader --max-request-retries 3 username
# Reasonable delays prevent detection
# 5-10 second delays between bulk operations
Session Best Practices
섹션 제목: “Session Best Practices”# Use persistent session
# Rotate user agents
# Don't run in parallel
# Respect Instagram's robots.txt
# Follow API rate limits
# Archive sessions for reuse
Legal Considerations
섹션 제목: “Legal Considerations”Terms of Service Compliance
섹션 제목: “Terms of Service Compliance”Instagram Terms Restrictions:
- Don't download content without authorization
- Don't bypass security measures
- Don't use for spam/harassment
- Respect privacy settings
Legal Usage:
- Personal research
- Academic purposes
- Authorized security assessments
- Public content only
- Attribution of content
Troubleshooting
섹션 제목: “Troubleshooting”Authentication Issues
섹션 제목: “Authentication Issues”Login Failures
섹션 제목: “Login Failures”# Clear old session
rm -rf ~/.local/share/instaloader/
# Re-authenticate
instaloader --login username --password password
# If 2FA enabled
# Respond to browser prompt
instaloader --login username
Session Expired
섹션 제목: “Session Expired”# Save fresh session
instaloader --login username --save-session fresh.json
# Use explicit session
instaloader --session fresh.json profile_name
Download Issues
섹션 제목: “Download Issues”No Results
섹션 제목: “No Results”# Verify profile exists
instaloader --login user target_username --count 1
# Check profile visibility
# Private accounts require following
# Test with public profile first
# Verify credentials
instaloader --login user --test-login
Partial Downloads
섹션 제목: “Partial Downloads”# Resume interrupted download
instaloader --login user profile_name
# Force re-download
rm profile_name/*.json
instaloader --login user profile_name
Rate Limiting
섹션 제목: “Rate Limiting””Too Many Requests”
섹션 제목: “”Too Many Requests””# Reduce request frequency
# Add delays between operations
sleep 30
# Try again later
instaloader --sleep-after-login 60 profile_name
# Use different session
instaloader --session backup.json profile_name
Advanced Python Usage
섹션 제목: “Advanced Python Usage”Custom Instaloader Scripts
섹션 제목: “Custom Instaloader Scripts”#!/usr/bin/env python3
import instaloader
from pathlib import Path
# Initialize loader
L = instaloader.Instaloader()
# Login
L.login("username", "password")
# Download profile
profile = instaloader.Profile.from_username(L.context, "target")
# Access profile attributes
print(f"Username: {profile.username}")
print(f"Followers: {profile.followers}")
print(f"Followed by: {profile.followed_by}")
# Iterate posts
for post in profile.get_posts():
print(f"Post: {post.caption[:50]}")
print(f"Likes: {post.likes}")
print(f"Comments: {post.comments}")
# Download specific post
L.download_post(post, target='./downloads')
# Logout
L.close()
Data Export
섹션 제목: “Data Export”Format and Structure
섹션 제목: “Format and Structure”JSON Metadata Format
섹션 제목: “JSON Metadata Format”{
"node": {
"id": "post_id",
"taken_at_timestamp": 1234567890,
"caption": "Post caption text",
"edge_liked_by": {"count": 1000},
"edge_media_to_comment": {"count": 50},
"owner": {
"username": "author"
}
}
}
Export to CSV
섹션 제목: “Export to CSV”#!/usr/bin/env python3
import json
import csv
import os
def export_to_csv(profile_dir, output_file):
"""Export posts to CSV"""
rows = []
for filename in os.listdir(profile_dir):
if not filename.endswith('.json'):
continue
with open(os.path.join(profile_dir, filename)) as f:
post = json.load(f)
rows.append({
'timestamp': post['taken_at_timestamp'],
'caption': post['caption'][:100],
'likes': post['edge_liked_by']['count'],
'comments': post['edge_media_to_comment']['count'],
'author': post['owner']['username']
})
# Write CSV
with open(output_file, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
# Usage
export_to_csv('target_username', 'posts.csv')
Resources
섹션 제목: “Resources”- Official Documentation: https://instaloader.github.io/
- GitHub Repository: https://github.com/instaloader/instaloader
- Community Discussions: GitHub Issues & Discussions
- Similar Tools: IG-Story-Downloader, Bulk Instagram Image Downloader
- Academic References: Social Media OSINT Papers
Version Information
섹션 제목: “Version Information”Current stable: Instaloader 4.13+ Language: Python 3.6+ Cross-platform: Linux, macOS, Windows Dependencies: requests License: MIT Active Development: Community-maintained