How Holehe's CSV Export Works and What Data It Includes
Holehe's CSV export is triggered by the -C/--csv flag and writes all OSINT scan results to a timestamped UTF-8 file using the export_csv() function in holehe/core.py.
When running email reconnaissance with holehe, you can persist findings to a structured CSV file for further analysis, reporting, or integration with other tools. According to the megadose/holehe source code, this export mechanism is lightweight yet comprehensive, capturing every data point returned by the 120+ supported modules.
How to Enable CSV Export in Holehe
Command-Line Usage
Pass the -C or --csv flag when executing holehe from the terminal:
$ holehe victim@example.com -C
The tool executes all modules, aggregates results, and writes them to a filename with the pattern holehe_<timestamp>_<email>_results.csv. Upon completion, holehe prints the full path to the exported file.
Where the Flag Is Parsed
The argument is defined in holehe/core.py at lines 192-194:
parser.add_argument("-C","--csv", default=False, required=False,
dest="csvoutput", action='store_true',
help="Create a csv with the results")
When args.csvoutput evaluates to True, the main execution flow calls export_csv(data, args, email) immediately after all modules complete.
The export_csv Function: Implementation Details
The core logic resides in holehe/core.py at lines 54-64:
def export_csv(data, args, email):
if args.csvoutput:
timestamp = int(time.time())
filename = f"holehe_{timestamp}_{email}_results.csv"
with open(filename, 'w', newline='', encoding='utf-8') as f:
fc = csv.DictWriter(f, fieldnames=data[0].keys())
fc.writeheader()
fc.writerows(data)
print(f"All results have been exported to {filename}")
Key implementation characteristics:
- Timestamped filenames prevent collisions when scanning the same target multiple times
newline=''ensures Windows compatibility by suppressing extra blank linescsv.DictWritermaps dictionary keys directly to CSV columns- UTF-8 encoding handles international characters in email addresses and response data
What Data Fields the CSV Contains
Each row in the exported CSV represents one module's execution result. The column headers derive dynamically from data[0].keys(), ensuring the CSV structure always matches the internal data format.
| Field | Description | Example Values |
|---|---|---|
name |
Internal module identifier | twitter, gmail, adobe |
domain |
Target service domain | twitter.com, adobe.com |
rateLimit |
Boolean indicating throttling status | True, False |
exists |
Boolean indicating account discovery | True (found), False (not found) |
emailrecovery |
Obfuscated recovery email | v***@gmail.com, None |
phoneNumber |
Obfuscated recovery phone | +1 ***-***-1234, None |
others |
Miscellaneous metadata | Full name, signup date, location, etc. |
These fields are populated by individual modules in holehe/modules/ and collected into the data list passed to export_csv().
Programmatic CSV Export Example
You can also invoke export_csv() directly when embedding holehe in Python applications:
import httpx
import trio
from holehe.core import export_csv, get_functions, import_submodules
async def scan_and_export(email: str):
# Load all OSINT modules
modules = import_submodules("holehe.modules")
functions = get_functions(modules)
# Collect results from all modules
results = []
async with httpx.AsyncClient(timeout=10) as client:
for func in functions:
await func(email, client, results)
# Export to CSV using minimal args object
class Args:
csvoutput = True
export_csv(results, Args(), email)
# Execute the scan
trio.run(scan_and_export, "target@example.com")
This approach mirrors the CLI behavior while allowing custom result processing before export.
CSV vs. Terminal Output: Key Differences
- Terminal output renders results as formatted tables with color-coded status indicators
- CSV export preserves the complete raw dataset including all metadata fields, even when
exists=False - CSV files include rate-limited and failed attempts, giving you visibility into data quality and coverage gaps
Summary
- Holehe's CSV export is implemented in the
export_csv()function withinholehe/core.py(lines 54-64) - Activation requires the
-C/--csvflag parsed at lines 192-194 of the same file - Output filenames follow the pattern
holehe_<timestamp>_<email>_results.csv - Seven standard fields capture module results:
name,domain,rateLimit,exists,emailrecovery,phoneNumber, andothers - The
csv.DictWriterclass generates headers dynamically from result dictionary keys
Frequently Asked Questions
Does holehe append to existing CSV files or overwrite them?
Holehe creates a new file with a Unix timestamp on every export, so existing files are never modified or overwritten. This design ensures historical scan preservation without manual file management.
What happens if no accounts are found—will the CSV still be created?
Yes. The CSV is generated regardless of findings, containing rows where exists=False for all queried services. This negative data is valuable for confirming account absence across platforms.
Can I customize the CSV filename or output directory?
The current implementation does not expose filename or path configuration through CLI arguments. To customize output locations, use the programmatic API and modify the filename variable in export_csv() before the file open operation.
Why does the CSV contain None values for some fields?
None appears when a service either does not provide recovery contact information or the module failed to extract it. The others field is particularly variable—populated only when modules return additional metadata beyond the standard schema.
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 →