Username‑Search CLI Clone (Python)

A minimal Sherlock‑style tool in 45 minutes

Welcome to another official UVF IT guide! In this quick build you’ll create a tiny command‑line utility that checks a handful of social‑media sites for the existence of a given username, inspired by the Sherlock project.

We’ll use plain Python, the free requests library, and a tiny JSON file of sites – no paid APIs, no Docker, just what’s on your laptop.

Before you start

Clone Architecture
LOCAL RUNTIME load query CLI Wrapper (Python) sites.json (site list) HTTP GET (requests)
1

Phase 1: Scaffold the project

Create a folder, a virtual environment, and add the site list file.

mkdir sherlock_clone && cd sherlock_clone
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install requests
cat > sites.json <<'EOF'
[
  {"name": "Twitter", "url": "https://twitter.com/{}"},
  {"name": "GitHub", "url": "https://github.com/{}"},
  {"name": "Instagram", "url": "https://www.instagram.com/{}"},
  {"name": "Reddit", "url": "https://www.reddit.com/user/{}"},
  {"name": "Pinterest", "url": "https://www.pinterest.com/{}"}
]
EOF
2

Phase 2: Core model – load sites

Read the JSON file into a Python list of dicts.

loader.py

import json
import pathlib

def load_sites(path: str = "sites.json") -> list[dict]:
    """Load the site definitions from a JSON file.
    Returns a list of dictionaries with keys 'name' and 'url'."""
    file_path = pathlib.Path(path)
    if not file_path.is_file():
        raise FileNotFoundError(f"Site list not found: {path}")
    with file_path.open(encoding="utf-8") as f:
        return json.load(f)

if __name__ == "__main__":
    sites = load_sites()
    print(f"Loaded {len(sites)} sites:")
    for s in sites:
        print(f"- {s['name']}: {s['url']}")
3

Phase 3: API & CLI – check usernames

In this step we turn the static site list into a working checker. The script reads *sites.json*, builds a URL for each service by inserting the target username, and makes a GET request. If the response returns HTTP 200 we consider the account existing and print a friendly [+] line; otherwise we stay silent. Keeping the logic simple makes it easy to extend later with concurrency or error handling.

sherlock_clone.py

import json, sys, requests

def load_sites(path='sites.json'):
    with open(path, 'r') as f:
        return json.load(f)

def check_username(username, sites):
    for site in sites:
        url = site['url'].replace('{username}', username)
        try:
            resp = requests.get(url, timeout=5)
            if resp.status_code == 200:
                print(f"[+] {site['name']}: {url}")
        except requests.RequestException:
            # network hiccup – just skip this site
            continue

if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('Usage: python sherlock_clone.py <username>')
        sys.exit(1)
    user = sys.argv[1]
    sites_data = load_sites()
    check_username(user, sites_data)
4

Phase 4: Run locally

Now that the checker is ready, we can try it against a real username. Activate your virtual environment, ensure *requests* is installed, and invoke the script with a sample handle. The output will list every service where the handle appears, each prefixed with [+] for quick scanning.

source venv/bin/activate
python sherlock_clone.py exampleuser
5

Phase 5: Verify & extend

After a successful run, verify that the console printed at least one [+] line (or none, which is also valid) and that no tracebacks appeared. To keep a permanent record, redirect the output to a file named after the searched username. You can now grow the tool by adding more entries to *sites.json* or by enhancing the script to write CSV/JSON logs.

python sherlock_clone.py exampleuser > exampleuser.txt

Verifying the Stack

CheckCommand / Why it matters
Virtual environment activated and requests installedsource venv/bin/activate && pip list | grep requests
Running the script prints at least one [+] line or none without errorpython sherlock_clone.py exampleuser
Output file created with same name as usernamecat exampleuser.txt

What’s next?

You now have a functional username‑search CLI. To approach the real Sherlock, expand sites.json to the full list, add concurrency with concurrent.futures, and implement CSV/JSON export options.