How Holehe's CSV Export Functionality Works: Complete Technical Guide
Holehe's CSV export is handled by the export_csv function in holehe/core.py, which writes scan results to a timestamped UTF-8 CSV file containing 7 standardized fields including account existence, rate limits, and recovery information.
Holehe is a popular OSINT tool for checking email address presence across hundreds of websites. When you need to preserve scan results for reporting or further analysis, the CSV export functionality provides a portable, structured format that captures every finding. This guide examines how the export system works, what data it captures, and how to use it both from the command line and programmatically.
How to Enable CSV Export in Holehe
The CSV feature is triggered by the -C or --csv flag when running Holehe from the command line. According to the megadose/holehe source code, this flag is defined in the argument parser at line 192-194 of holehe/core.py:
parser.add_argument("-C","--csv", action='store_true', dest="csvoutput",
help="Create a csv with the results")
When args.csvoutput evaluates to True, Holehe automatically invokes export_csv() after completing the email scan across all modules.
Command Line Usage
# Basic CSV export
$ holehe victim@example.com -C
All results have been exported to holehe_1723862123_victim@example.com_results.csv
# Combine with other flags
$ holehe victim@example.com -C --no-tqdm --only-used
The filename follows a predictable pattern: holehe_<timestamp>_<email>_results.csv. This naming convention prevents overwrites and preserves scan context.
The export_csv Function Implementation
The core CSV logic resides in export_csv at lines 54-64 of holehe/core.py. Here is the actual implementation structure:
def export_csv(data, args, email):
if args.csvoutput:
name = "holehe_" + str(int(time.time())) + "_" + str(email) + "_results.csv"
with open(name, 'w', newline='', encoding='utf-8') as f:
if data:
fc = csv.DictWriter(f, fieldnames=data[0].keys())
fc.writeheader()
fc.writerows(data)
Key implementation details from the source:
newline='': Prevents extra blank lines on Windows systemsencoding='utf-8': Ensures universal character compatibilitycsv.DictWriter: Maps dictionary keys directly to CSV columns- Dynamic headers:
fieldnames=data[0].keys()guarantees column order matches the internal data structure
The function requires no explicit return; it writes the file and allows normal program termination.
What Data Holehe's CSV Export Includes
Each row in the exported CSV represents one module's result. The 7 standard fields captured in every scan are:
| Field | Type | Description |
|---|---|---|
name |
string | Internal module identifier (e.g., twitter, gmail, adobe) |
domain |
string | Target website domain (e.g., twitter.com, gmail.com) |
rateLimit |
boolean | True if the request encountered rate limiting |
exists |
boolean | True when an account matches the target email |
emailrecovery |
string|None | Partially-obfuscated recovery email from the service |
phoneNumber |
string|None | Partially-obfuscated recovery phone number |
others |
dict|None | Additional metadata (full name, creation date, etc.) |
These fields originate from individual modules in holehe/modules/*. Each module returns a standardized dictionary that export_csv aggregates into the final dataset.
Sample CSV Output Structure
name,domain,rateLimit,exists,emailrecovery,phoneNumber,others
twitter,twitter.com,False,True,vi***@gmail.com,+1 *** *** 1234,"{'fullname': 'John Doe'}"
gmail,gmail.com,False,True,None,None,None
adobe,adobe.com,False,False,None,None,None
github,github.com,True,False,None,None,None
Note the rate limit indicator on the GitHub row—this distinction matters for result interpretation.
Programmatic CSV Export with Holehe
You can leverage export_csv directly in Python scripts for custom workflows. This approach requires constructing a compatible argument object:
import httpx
import trio
from holehe.core import export_csv, get_functions, import_submodules
async def scan_and_export(email: str, output_csv: bool = True):
"""
Run Holehe scan and optionally export to CSV.
"""
# Load all OSINT modules
modules = import_submodules("holehe.modules")
functions = get_functions(modules)
# Collect results
results = []
async with httpx.AsyncClient(timeout=10) as client:
for func in functions:
await func(email, client, results)
# Export to CSV if requested
if output_csv:
class Args:
csvoutput = True
export_csv(results, Args(), email)
print(f"Exported {len(results)} results for {email}")
return results
# Execute scan
trio.run(scan_and_export, "target@example.com")
This pattern is useful for:
- Batch processing multiple email addresses
- Integrating Holehe into larger reconnaissance pipelines
- Custom filtering before export
CSV vs. JSON Output: Key Differences
Holehe supports multiple output formats. Understanding CSV's specific characteristics helps you choose appropriately:
| Aspect | CSV Export | JSON Export |
|---|---|---|
| Human readability | Excellent in spreadsheet tools | Requires parsing |
| Schema flexibility | Fixed column order from data[0].keys() |
Preserves nested structures in others |
| File size | Smaller for flat data | Larger due to repeated keys |
| Nested data handling | others field flattened as string |
Native nested object support |
| Tool compatibility | Excel, Google Sheets, pandas | APIs, MongoDB, jq |
The others field in CSV contains serialized dictionary data—parse it with ast.literal_eval or json.loads if you need programmatic access to nested values.
Source Files and Reference
The Holehe CSV export functionality spans these key locations in the megadose/holehe repository:
holehe/core.pylines 54-64:export_csvfunction implementationholehe/core.pylines 190-194:-C/--csvargument parsingholehe/modules/*: Module result generation (e.g.,adobe.py,twitter.py)README.mdlines 73-84: Output format documentation
For the most current implementation, verify against the master branch as the tool actively evolves.
Summary
- CSV export is triggered by
-C/--csvand handled byexport_csv()inholehe/core.py - Auto-generated filenames include timestamps:
holehe_<timestamp>_<email>_results.csv - Seven standardized fields capture module name, domain, rate limits, account existence, recovery email, phone number, and miscellaneous data
- UTF-8 encoding with
newline=''ensures cross-platform compatibility - Programmatic access requires creating an
Argsclass withcsvoutput = True
Frequently Asked Questions
Does Holehe's CSV export include the raw HTTP responses?
No. The CSV contains only processed results—module identifiers, existence flags, and extracted metadata. Raw HTTP responses are not preserved; they are processed by each module in holehe/modules/* and distilled into the standardized 7-field structure before export.
Can I customize which columns appear in the CSV output?
Not directly through command-line flags. The export_csv function dynamically builds headers from data[0].keys(), so column selection would require modifying the result dictionaries before calling export_csv() programmatically.
What happens if all modules return rate limits?
The CSV still generates with all rows present. Each rate-limited module shows rateLimit: True and typically exists: False since the existence check could not complete. Review the rateLimit column to distinguish inconclusive results from confirmed negatives.
Is the CSV format stable across Holehe versions?
The 7-field structure (name, domain, rateLimit, exists, emailrecovery, phoneNumber, others) has remained consistent, but verify against your installed version. The dynamic header generation in export_csv adapts to any new fields modules might add.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →