How to Parse Holehe Output: Complete Guide to the Python Library and CSV Export

Holehe returns investigation results as a standardized Python dictionary list stored in the out variable, which you can capture directly when using the tool as a library or export to CSV via the --csv flag for universal parsing.

Learning how to parse Holehe output effectively allows you to integrate this email investigation tool into automated workflows and analytics pipelines. The megadose/holehe repository structures every service check result into a predictable schema, making it straightforward to extract registration status, recovery information, and rate-limiting data programmatically or from file exports.

Understanding the Holehe Data Structure

The Standard Result Dictionary Schema

Each email verification produces a Python dictionary with eight standardized keys. According to the error-handling fallback in launch_module within holehe/core.py (lines 70-78), the schema remains consistent whether a module succeeds or fails:

  • name: The internal module identifier (e.g., instagram)
  • domain: Human-readable service domain (e.g., instagram.com)
  • exists: Boolean indicating if the email is registered on the service
  • rateLimit: Boolean flag set to True when the request hits rate limits
  • error: Boolean flag set to True when the module raises an exception
  • emailrecovery: Partially obfuscated recovery email address, if available
  • phoneNumber: Partially obfuscated phone number associated with the account, if any
  • others: Nested dictionary containing service-specific data such as FullName or account creation timestamps

Individual modules populate these values in files like holehe/modules/social_media/instagram.py, but the key structure remains uniform across all 120+ supported services.

Method 1: Parse Holehe Output Programmatically (Python Library)

The most robust way to parse Holehe output is importing the tool as a Python library and capturing the out list directly before it reaches the display functions. The orchestration logic in holehe/core.py uses launch_module to populate this list asynchronously.

import httpx
import trio
import json
from holehe.core import import_submodules, get_functions, launch_module

async def investigate_email(email):
    # Load all service modules

    modules = import_submodules("holehe.modules")
    websites = get_functions(modules)
    
    # Initialize HTTP client and result container

    client = httpx.AsyncClient(timeout=10)
    out = []
    
    # Execute checks concurrently

    async with trio.open_nursery() as nursery:
        for site in websites:
            nursery.start_soon(launch_module, site, email, client, out)
    
    await client.aclose()
    return out  # List of dictionaries ready for parsing

# Usage example

results = trio.run(investigate_email, "target@example.com")

# Parse specific fields

for result in results:
    if result["exists"] and not result["error"]:
        print(f"{result['domain']}: Account found")
        if result["emailrecovery"]:
            print(f"  Recovery hint: {result['emailrecovery']}")

# Convert entire output to JSON for downstream processing

json_output = json.dumps(results, indent=2)

The out list contains the raw data before print_result (lines 6-49) formats it for terminal display or export_csv (lines 54-64) writes it to disk. This approach bypasses file I/O entirely and provides immediate access to the others dictionary for advanced data extraction.

Method 2: Parse Holehe Output via CSV Export

For shell scripting or non-Python environments, use the CLI's built-in CSV export functionality. The export_csv function in holehe/core.py (lines 54-64) generates machine-readable files with headers matching the dictionary keys exactly.

holehe target@example.com --csv

This creates a timestamped file following the pattern holehe_1700000000_target@example.com_results.csv in the current directory. Parse this file using standard CSV libraries:

import csv
import glob

# Find the generated CSV file

csv_files = glob.glob("holehe_*_target@example.com_results.csv")
latest_file = max(csv_files, key=lambda x: x.split('_')[1])

# Parse into dictionaries

with open(latest_file, mode='r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    results = list(reader)

# Filter for confirmed accounts

confirmed_accounts = [
    r for r in results 
    if r["exists"] == "True" and r["error"] == "False"
]

The CSV columns map directly to the dictionary keys (name, domain, exists, rateLimit, error, emailrecovery, phoneNumber, others), ensuring consistent parsing across Python pandas, JavaScript PapaParse, or spreadsheet applications.

Method 3: Parse Plain Text Output (Optional)

If you must parse the terminal output directly, suppress ANSI color codes using the --no-color flag to simplify regex extraction. The print_result function in holehe/core.py (lines 8-12) checks args.nocolor to disable formatting.

holehe target@example.com --no-color --no-clear > results.txt

However, this method is fragile compared to the programmatic or CSV approaches, as terminal formatting changes may break parsing logic. Use this only when library installation is impossible.

Key Files Involved in Output Generation

Understanding the source architecture helps debug parsing issues:

  • holehe/core.py: Contains the launch_module async worker (lines 66-78) that assembles results, print_result (lines 6-49) for terminal formatting, and export_csv (lines 54-64) for file export
  • holehe/modules/*/*.py: Individual service implementations that populate the result dictionaries with service-specific data in the others field
  • README.md (Module Output section): Documents the JSON-equivalent format specification for reference

Summary

  • Holehe structures every result as a Python dictionary with eight standardized keys including exists, rateLimit, and emailrecovery, collected into a list called out.
  • Import Holehe as a library to capture the out list directly from launch_module before display processing, enabling real-time filtering and JSON serialization.
  • Use the --csv flag to generate timestamped CSV files parseable by any standard library, with columns matching the internal dictionary schema exactly.
  • Reference holehe/core.py lines 66-78 for the result assembly logic and lines 54-64 for the CSV export implementation when building custom parsers.

Frequently Asked Questions

What is the exact schema of a Holehe result dictionary?

Each result contains the keys name, domain, exists, rateLimit, error, emailrecovery, phoneNumber, and others. The exists boolean indicates account registration status, while rateLimit and error signal operational issues. The others field holds service-specific metadata such as full names or creation dates as a nested dictionary.

How do I export Holehe results to CSV from the command line?

Append the --csv flag to any Holehe command: holehe email@example.com --csv. The tool generates a timestamped CSV file named holehe_[timestamp]_email@example.com_results.csv with headers matching the internal dictionary keys. This file can be parsed by Python's csv.DictReader, pandas, or any spreadsheet software.

Can I use Holehe as a Python library instead of CLI?

Yes. Import import_submodules, get_functions, and launch_module from holehe.core, then execute launch_module within a trio nursery to populate an out list. This list contains the raw result dictionaries before they are formatted for display, allowing direct programmatic access to all investigation data without file I/O.

Where does Holehe assemble the final result list before display?

The launch_module function in holehe/core.py (lines 66-78) appends each module's result to the out list passed as an argument. After all async workers complete, holehe/core.py sorts this list by the name key (alphabetically by service) and passes it to either print_result (lines 6-49) for terminal display or export_csv (lines 54-64) for file export.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →