Skip to main content

InstaHarvest 🌾

Python Version PyPI version License Downloads GitHub stars

Professional Instagram Data Collection Toolkit — Powerful library for Instagram automation, data collection, and analytics built on Playwright.

📖 Documentation | 🐛 Report Bug | 💡 Request Feature | 📋 Changelog


✨ Features

Category Capabilities
📊 Profile Stats, verified badge, category, full bio, external links, Threads
🔌 Web API 16+ JSON endpoints — profiles, followers, feed, comments, reels, stories, hashtags
📸 Content Posts, Reels, Stories, Highlights, Tagged Posts — with JSON-first architecture
💬 Engagement Comments (with replies), likes, media download (images/videos via yt-dlp)
👥 Social Followers/Following lists, Follow/Unfollow, Direct Messaging
🔍 Discovery Search, Hashtag feeds, Location feeds, Explore, Notifications
⚡ Performance Parallel processing, SharedBrowser (1 browser for all), Excel export
🛡️ Reliability Rate limiting, graceful shutdown (Ctrl+C), auto-save, retry logic

🚀 Installation & Setup

# Install from PyPI
pip install instaharvest
playwright install chrome

# OR install from GitHub (latest dev version)
git clone https://github.com/mpython77/insta-harvester.git
cd insta-harvester
pip install -r requirements.txt
playwright install chrome

Create Instagram session (required, one-time):

from instaharvest import save_session
save_session()
# Browser opens → Login manually → Press ENTER → Session saved ✅

⚠️ Without instagram_session.json, the library won't work.


📖 Quick Start — SharedBrowser (Recommended)

One browser for ALL operations — fastest and most efficient way to use InstaHarvest.

from instaharvest import SharedBrowser
from instaharvest.config import ScraperConfig

config = ScraperConfig()

with SharedBrowser(config=config) as browser:
    # ── Profile ──
    profile = browser.scrape_profile("username")
    print(f"{profile.full_name}: {profile.followers} followers")

    # ── Social Actions ──
    browser.follow("user1")
    browser.send_message("user1", "Hello!")
    followers = browser.get_followers("user2", limit=100)

    # ── Content Scraping ──
    post = browser.scrape_post("https://www.instagram.com/p/ABC/")
    reel = browser.scrape_reel("https://www.instagram.com/reel/XYZ/")
    stories = browser.scrape_stories("username")
    comments = browser.scrape_comments("https://www.instagram.com/p/ABC/")

    # ── Discovery ──
    results = browser.search("fashion brands")
    hashtag = browser.scrape_hashtag("streetwear")
    notifs = browser.read_notifications()

    # ── Batch Operations ──
    posts = browser.scrape_posts(["url1", "url2", "url3"])
    files = browser.download_post("https://www.instagram.com/p/ABC/")

    # ── Web API (Direct JSON — exact data) ──
    profile_json = browser.get_profile_json("username")
    print(f"Exact followers: {profile_json.follower_count:,}")

    feed = browser.get_user_feed_api(profile_json.user_id, count=5)
    reels = browser.get_reels_api(profile_json.user_id)
    highlights = browser.get_highlights_api(profile_json.user_id)

📚 API Reference

1. Profile Scraping

from instaharvest import ProfileScraper
from instaharvest.config import ScraperConfig

config = ScraperConfig()
scraper = ProfileScraper(config=config)
session_data = scraper.load_session()
scraper.setup_browser(session_data)

profile = scraper.scrape('username')
print(f"Posts: {profile.posts}, Followers: {profile.followers}")
print(f"Verified: {profile.is_verified}, Category: {profile.category}")
print(f"Bio: {profile.bio}, Links: {profile.external_links}")

scraper.close()

2. Followers / Following

from instaharvest import FollowersCollector
from instaharvest.config import ScraperConfig

config = ScraperConfig()
collector = FollowersCollector(config=config)
session_data = collector.load_session()
collector.setup_browser(session_data)

followers = collector.get_followers('username', limit=100, print_realtime=True)
following = collector.get_following('username', limit=50)

collector.close()

3. Follow / Unfollow & Direct Messaging

from instaharvest import FollowManager, MessageManager
from instaharvest.config import ScraperConfig

config = ScraperConfig()

# Follow
manager = FollowManager(config=config)
session_data = manager.load_session()
manager.setup_browser(session_data)
manager.follow('username')
manager.batch_follow(['user1', 'user2', 'user3'])
manager.close()

# DM
messenger = MessageManager(config=config)
session_data = messenger.load_session()
messenger.setup_browser(session_data)
messenger.send_message('username', 'Hello!')
messenger.batch_send(['user1', 'user2'], 'Hi there!')
messenger.close()

4. Post & Reel Data (JSON-First)

from instaharvest import PostDataScraper
from instaharvest.config import ScraperConfig

config = ScraperConfig()
scraper = PostDataScraper(config=config)
session_data = scraper.load_session()
scraper.setup_browser(session_data)

post = scraper.scrape('https://www.instagram.com/p/DVs7LK-iO0C/')

# 30+ fields extracted automatically from JSON
print(post.like_count, post.comment_count)     # Engagement
print(post.caption, post.tagged_accounts)       # Content
print(post.location.name if post.location else 'N/A')  # Location
print(post.owner.username if post.owner else 'N/A')     # Owner

for slide in post.carousel_slides:              # Carousel
    print(f"  Slide {slide.slide_index}: {slide.media_type}")

scraper.close()

5. Comment Scraping

from instaharvest import CommentScraper
from instaharvest.exporters import export_comments_to_json, export_comments_to_excel
from instaharvest.config import ScraperConfig

config = ScraperConfig()
scraper = CommentScraper(config=config)
session_data = scraper.load_session()
scraper.setup_browser(session_data)

result = scraper.scrape(
    'https://www.instagram.com/p/POST_ID/',
    max_comments=100,
    include_replies=True
)

for comment in result.comments:
    print(f"@{comment.author.username}: {comment.text}")
    for reply in comment.replies:
        print(f"  ↳ @{reply.author.username}: {reply.text}")

# Export
export_comments_to_json(result, 'comments.json')
export_comments_to_excel(result, 'comments.xlsx')

scraper.close()

6. Stories & Highlights

from instaharvest import StoryScraper, HighlightsScraper
from instaharvest.config import ScraperConfig

config = ScraperConfig()

# Stories — JSON-first, per-slide tag mapping
scraper = StoryScraper(config=config)
session_data = scraper.load_session()
scraper.setup_browser(session_data)

result = scraper.scrape('username', extract_tags=True)
print(f"Stories: {result.story_count}, Tags: {result.all_tagged_accounts}")
for slide in result.slides:
    print(f"  Slide {slide.slide_index}: [{slide.media_type}] {slide.timestamp} → {slide.tagged_accounts}")

scraper.close()

# Highlights — mentions, links, music, locations
hl_scraper = HighlightsScraper(config=config)
session = hl_scraper.load_session()
hl_scraper.setup_browser(session)

full = hl_scraper.scrape_all('mondayswimwear', max_slides_per=100)
print(f"{full.total_highlights} highlights, {full.total_slides} total slides")

hl_scraper.close()

7. Parallel Processing & Orchestrator

from instaharvest import SharedBrowser, InstagramOrchestrator
from instaharvest.config import ScraperConfig

config = ScraperConfig(headless=True)

with SharedBrowser(config=config) as browser:
    orch = InstagramOrchestrator(config, shared_browser=browser)

    results = orch.scrape_complete_profile_advanced(
        'username',
        parallel=3,
        save_excel=True,
        scrape_comments=True,
        scrape_stories=True
    )
    print(f"Scraped {len(results['posts_data'])} posts")

8. Tagged Posts

from instaharvest import TaggedPostsScraper
from instaharvest.config import ScraperConfig

config = ScraperConfig()
scraper = TaggedPostsScraper(config=config)
session = scraper.load_session()
scraper.setup_browser(session)

result = scraper.scrape('mondayswimwear', max_posts=100)
print(f"Total: {result.total_found} tagged posts, Unique taggers: {result.unique_taggers}")
for post in result.tagged_posts:
    print(f"  @{post.owner} → {post.url} ({post.media_type})")

scraper.close()

9. Notifications

from instaharvest import SharedBrowser
from instaharvest.config import ScraperConfig

config = ScraperConfig()
with SharedBrowser(config=config) as browser:
    notifs = browser.read_notifications()
    print(f"Total: {len(notifs)} notifications")

Notification types: follow, post_like, comment_like, comment, mention, follow_request, follow_accepted, thread, story, system

10. Media Download

from instaharvest import SharedBrowser
from instaharvest.config import ScraperConfig

config = ScraperConfig()
with SharedBrowser(config=config) as browser:
    # Handles images, videos, reels, carousels automatically
    files = browser.download_post("https://www.instagram.com/reel/C-example...")
    print(f"Downloaded {len(files)} files")

🔧 Video support requires Google Chrome (browser_channel='chrome', the default). Chromium lacks video codecs.


🔌 Web API — Direct JSON Data Extraction

Access Instagram's internal API endpoints directly through Playwright. Returns exact, structured data — no DOM scraping.

16+ endpoints | 15 data models | Auto-pagination | Rate limiting | POST + GET support

from instaharvest import SharedBrowser
from instaharvest.config import ScraperConfig

config = ScraperConfig(headless=True)

with SharedBrowser(config=config) as browser:
    # ── Profile (exact stats) ──
    profile = browser.get_profile_json('mondayswimwear')
    print(f"{profile.full_name}: {profile.follower_count:,} followers")
    user_id = profile.user_id

    # ── Followers / Following ──
    followers = browser.get_followers_api(user_id, count=50)
    following = browser.get_following_api(user_id, count=50)

    # ── Feed, Comments, Likers ──
    feed = browser.get_user_feed_api(user_id, count=12)
    comments = browser.get_media_comments_api(feed.posts[0].media_id)
    likers = browser.get_media_likers_api(feed.posts[0].media_id)

    # ── Stories, Highlights, Reels ──
    stories = browser.get_stories_api(user_id)
    highlights = browser.get_highlights_api(user_id)
    reels = browser.get_reels_api(user_id)

    # ── Hashtag & Location ──
    hashtag = browser.get_hashtag_feed_api('swimwear')
    location = browser.get_location_feed_api('213385402')

    # ── Raw API (any endpoint, GET or POST) ──
    raw = browser.fetch_raw_api('/api/v1/users/1059031072/info/')

Available Endpoints:

Method Description Returns
get_profile_json(username) Profile with exact stats WebProfileData
get_user_info(user_id) Profile by ID WebProfileData
get_followers_api(id, count) Followers list (paginated) FollowListResult
get_following_api(id, count) Following list (paginated) FollowListResult
get_friendship_status(id) Follow relationship FriendshipStatus
get_user_feed_api(id, count) User's posts UserFeedResult
get_media_info_api(media_id) Detailed post info MediaInfo
get_media_comments_api(id) Post comments CommentsResult
get_media_likers_api(id) Post likers LikersResult
get_stories_api(id) Active stories List[StoryMediaItem]
get_highlights_api(id) Highlights list HighlightsResult
get_reels_api(id) Reels with plays ReelsResult
get_hashtag_feed_api(tag) Hashtag posts HashtagSection
get_location_feed_api(id) Location posts LocationSection
get_tagged_posts_api(id) Tagged posts UserFeedResult
fetch_raw_api(endpoint) Any endpoint (GET/POST) Dict

Direct API access (without SharedBrowser):

from instaharvest import InstagramWebAPI
from playwright.sync_api import sync_playwright

with sync_playwright() as pw:
    browser = pw.chromium.launch(headless=True)
    context = browser.new_context(storage_state='instagram_session.json')
    page = context.new_page()
    page.goto('https://www.instagram.com/')

    api = InstagramWebAPI(page=page)
    profile = api.get_profile('mondayswimwear')
    print(f"{profile.follower_count:,} followers")

    browser.close()

🎯 Complete Workflow Example

from instaharvest import SharedBrowser, InstagramOrchestrator
from instaharvest.config import ScraperConfig

config = ScraperConfig()

with SharedBrowser(config=config) as browser:
    # 1. Profile analysis
    profile = browser.scrape_profile('target_user')
    print(f"📊 {profile.full_name}: {profile.followers} followers")

    # 2. Collect & follow
    followers = browser.get_followers('target_user', limit=50)
    for f in followers[:10]:
        browser.follow(f)

    # 3. Scrape posts
    post_links = browser.scrape_post_links('target_user')
    posts = browser.scrape_posts([l['url'] for l in post_links[:5]])

    # 4. Stories + Web API
    stories = browser.scrape_stories('target_user')
    profile_json = browser.get_profile_json('target_user')
    reels = browser.get_reels_api(profile_json.user_id)

    # 5. Full orchestrated scrape
    orch = InstagramOrchestrator(config, shared_browser=browser)
    results = orch.scrape_complete_profile_advanced(
        'target_user', parallel=3,
        save_excel=True, scrape_stories=True
    )
    print(f"✅ {len(results['posts_data'])} posts scraped")

📁 Project Structure

🗂️ Package Structure
insta-harvester/
├── instaharvest/              # Main package
│   ├── __init__.py            # Package entry point
│   ├── base.py                # Base scraper class
│   ├── config.py              # Configuration
│   ├── profile.py             # Profile scraping
│   ├── followers.py           # Followers collection
│   ├── follow.py              # Follow/unfollow
│   ├── message.py             # Direct messaging
│   ├── post_data.py           # Post data (JSON-first)
│   ├── reel_data.py           # Reel data extraction
│   ├── comment_scraper.py     # Comments with replies
│   ├── story_scraper.py       # Story scraping
│   ├── highlight_scraper.py   # Highlights extraction
│   ├── tagged_posts.py        # Tagged posts
│   ├── notifications.py       # Notification reader
│   ├── web_api.py             # 🔌 Web API (16+ endpoints)
│   ├── shared_browser.py      # SharedBrowser
│   ├── orchestrator.py        # Workflow orchestrator
│   ├── parallel_scraper.py    # Parallel processing
│   ├── downloader.py          # Media download
│   └── ...                    # More modules
├── examples/
│   ├── save_session.py        # Session setup
│   ├── all_in_one.py          # Interactive demo
│   ├── main_advanced.py       # Production scraping
│   ├── example_web_api.py     # 🔌 Web API demo
│   └── example_custom_config.py
├── tests/                     # 130+ unit tests
└── LICENSE                    # MIT License

⚙️ Configuration

from instaharvest import ScraperConfig

config = ScraperConfig(
    headless=True,              # Run without browser UI
    viewport_width=1920,
    viewport_height=1080,
    default_timeout=30000,      # 30 seconds
    max_scroll_attempts=50,
    log_level='INFO',
    # Rate limiting
    follow_delay_min=10.0,
    follow_delay_max=15.0,
    message_delay_min=15.0,
    message_delay_max=20.0,
)

See Configuration Guide for all options.


🔧 Troubleshooting

🔍 Common Issues & Solutions
Problem Solution
playwright command not found pip install playwright && playwright install chrome
No module named 'instaharvest' pip install instaharvest or pip install -e .
Session file not found Run save_session() first
Login required / Session expired Re-run save_session()
Instagram says 'Try again later' Increase rate limiting delays in config
Could not follow/unfollow Increase popup_open_delay and action_delay_*
Slow internet errors Increase page_load_delay and scroll_delay_*
Posts: 0 but content exists Update to latest version (v2.7.1+)

Getting Help:


⚠️ Disclaimer

This tool is for educational purposes only. Follow Instagram's Terms of Service, respect rate limits, and use responsibly.


📜 License

MIT License — see LICENSE for details.


🤝 Contributing

Contributions welcome! Submit a Pull Request.


Made with ❤️ by Muydinov Doston

Happy Harvesting! 🌾

Metadata

Release files for instaharvest 2.16.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for instaharvest 2.16.0
File Size Uploaded Provenance Actions
instaharvest-2.16.0.tar.gz 240.4 kB Without provenance Details for instaharvest-2.16.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for instaharvest 2.16.0
File Interpreter ABI Platform Actions
instaharvest-2.16.0-py3-none-any.whl Python 3 none any Details for instaharvest-2.16.0-py3-none-any.whl

Total release size: 482.5 kB

Release files / instaharvest-2.16.0.tar.gz

Download URL instaharvest-2.16.0.tar.gz
Size 240.4 kB
Tags Source
SHA-256 checksum
How to use checksums
e9da0051a69fa9494d800b95804e0cde2de6b7c2a75930ffe6091c6b4a20173d
BLAKE2b-256 checksum
How to use checksums
48d8e5705b3501e9728c8b72c49b4b9a35e15ead63f5e03bc5146dfad978e227
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release files / instaharvest-2.16.0-py3-none-any.whl

Download URL instaharvest-2.16.0-py3-none-any.whl
Size 242.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
11c9ab51749d9d4f5c191c6459336a1b88d09cda933e9f97cea8eb4b23a5ecf8
BLAKE2b-256 checksum
How to use checksums
e2b9d420ff9b291e6a8d91d043a9f1acead414e318ff3e2a1854474bb421e0ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Security for instaharvest 2.16.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page