Instaloader
Overview
Abschnitt betitelt „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
Abschnitt betitelt „Installation“Linux (Debian/Ubuntu)
Abschnitt betitelt „Linux (Debian/Ubuntu)“sudo apt-get update
sudo apt-get install python3 python3-pip
pip3 install instaloader
brew install python3
pip3 install instaloader
Windows
Abschnitt betitelt „Windows“# Python 3.6+ required
python -m pip install instaloader
FROM python:3.11-slim
RUN pip install instaloader
ENTRYPOINT ["instaloader"]
Build from Source
Abschnitt betitelt „Build from Source“git clone https://github.com/instaloader/instaloader.git
cd instaloader
python3 -m pip install -e .
Verify Installation
Abschnitt betitelt „Verify Installation“instaloader --version
instaloader -h
Basic Usage
Abschnitt betitelt „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
Abschnitt betitelt „Command-Line Options“Profile Options
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Authentication“Session Management
Abschnitt betitelt „Session Management“First-Time Login
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Profile Analysis“Download Complete Profile
Abschnitt betitelt „Download Complete Profile“Basic Profile Download
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Extract Profile Information“Profile Metadata Analysis
Abschnitt betitelt „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
Abschnitt betitelt „Download Stories“Story Collection
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Download Highlights“Story Highlights Preservation
Abschnitt betitelt „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
Abschnitt betitelt „Hashtag and Location Analysis“Hashtag Research
Abschnitt betitelt „Hashtag Research“Download Hashtag Posts
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Location Research“Download Location Posts
Abschnitt betitelt „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
Abschnitt betitelt „Advanced Workflows“OSINT Intelligence Gathering
Abschnitt betitelt „OSINT Intelligence Gathering“Complete Profile Intelligence
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Content Analysis“Post Metadata Extraction
Abschnitt betitelt „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
Abschnitt betitelt „Video and Media Download“Download Video Content
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Rate Limiting and Ethics“Responsible Usage
Abschnitt betitelt „Responsible Usage“Request Rate Limiting
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Legal Considerations“Terms of Service Compliance
Abschnitt betitelt „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
Abschnitt betitelt „Troubleshooting“Authentication Issues
Abschnitt betitelt „Authentication Issues“Login Failures
Abschnitt betitelt „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
Abschnitt betitelt „Session Expired“# Save fresh session
instaloader --login username --save-session fresh.json
# Use explicit session
instaloader --session fresh.json profile_name
Download Issues
Abschnitt betitelt „Download Issues“No Results
Abschnitt betitelt „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
Abschnitt betitelt „Partial Downloads“# Resume interrupted download
instaloader --login user profile_name
# Force re-download
rm profile_name/*.json
instaloader --login user profile_name
Rate Limiting
Abschnitt betitelt „Rate Limiting“”Too Many Requests”
Abschnitt betitelt „”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
Abschnitt betitelt „Advanced Python Usage“Custom Instaloader Scripts
Abschnitt betitelt „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
Abschnitt betitelt „Data Export“Format and Structure
Abschnitt betitelt „Format and Structure“JSON Metadata Format
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „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
Abschnitt betitelt „Version Information“Current stable: Instaloader 4.13+ Language: Python 3.6+ Cross-platform: Linux, macOS, Windows Dependencies: requests License: MIT Active Development: Community-maintained