# How Holehe Parses HTML Responses for Login Form Analysis

> Learn how Holehe parses HTML responses using BeautifulSoup and httpx to analyze login forms, extract hidden fields and CSRF tokens, and detect email registration.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: how-to-guide
- Published: 2026-08-24

---

**Holehe analyzes login forms by fetching pages asynchronously with httpx, parsing HTML with BeautifulSoup to extract hidden form fields and CSRF tokens, then reconstructing and submitting payloads to detect whether an email address is already registered.**

Holehe is an open-source OSINT tool that verifies if an email address is registered across thousands of services. For many platforms, the detection mechanism relies on the ability to parse HTML responses from login pages, reconstruct authentication requests, and interpret the resulting indicators to determine account existence.

## The Five-Step HTML Parsing Workflow

Holehe modules follow a consistent pattern defined in the source code to analyze login forms. The workflow leverages **BeautifulSoup** (imported centrally in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py)) combined with asynchronous HTTP requests.

### 1. Asynchronous Page Fetching

Each module uses `httpx.AsyncClient` to retrieve the target login page without blocking the execution flow. This initial request captures the raw HTML structure required for subsequent analysis.

```python

# Pattern seen in holehe/modules/shopping/amazon.py

headers = {"User-agent": random.choice(ua["browsers"]["chrome"])}
url = "https://www.amazon.com/ap/signin?...&"
req = await client.get(url, headers=headers)

```

### 2. DOM Parsing with BeautifulSoup

The response text is passed to BeautifulSoup with the standard `html.parser` engine. This creates a searchable DOM-like object that modules can query using CSS selectors or traversal methods.

```python
body = BeautifulSoup(req.text, "html.parser")

```

### 3. Form Field Extraction

Modules extract required fields—particularly hidden inputs and CSRF tokens—using either CSS selectors like `body.select("form input")` or targeted string splitting for specific token patterns.

```python

# Extracting hidden inputs from Amazon's sign-in form

data = {x["name"]: x["value"] for x in body.select("form input")
        if "name" in x.attrs and "value" in x.attrs}

```

### 4. Payload Reconstruction

The extracted name-value pairs are combined with the target email address into a dictionary that mimics a legitimate browser submission. This payload is then sent via POST (or occasionally GET) to the service's authentication endpoint.

```python
data["email"] = email
req = await client.post("https://www.amazon.com/ap/signin/", data=data)

```

### 5. Result Interpretation

After submission, Holehe inspects the response HTML or JSON for known markers indicating account existence, such as specific error divs or confirmation messages.

```python
if body.find("div", {"id": "auth-password-missing-alert"}):
    out.append({"exists": True, ...})

```

## Real-World Implementation Examples

The Holehe codebase demonstrates multiple strategies for parsing HTML responses depending on the target site's structure.

### Amazon: Full Form Extraction

In [`holehe/modules/shopping/amazon.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/shopping/amazon.py), the module retrieves the sign-in page and uses BeautifulSoup to select all `<input>` elements within `<form>` tags. It extracts every hidden field, injects the target email, and checks for the `auth-password-missing-alert` div to confirm the account exists.

```python

# Example: Amazon login-form parsing (holehe/modules/shopping/amazon.py)

headers = {"User-agent": random.choice(ua["browsers"]["chrome"])}
url = "https://www.amazon.com/ap/signin?...&"
req = await client.get(url, headers=headers)               # 1️⃣ fetch page

body = BeautifulSoup(req.text, "html.parser")              # 2️⃣ parse HTML

# 3️⃣ collect all hidden inputs from the form

data = {x["name"]: x["value"] for x in body.select("form input")
        if "name" in x.attrs and "value" in x.attrs}
data["email"] = email                                      # 4️⃣ add target e‑mail

req = await client.post("https://www.amazon.com/ap/signin/", data=data)

# 5️⃣ check response for a known “already‑used” element

if body.find("div", {"id": "auth-password-missing-alert"}):
    out.append({"exists": True, ...})

```

### MySpace: CSRF Token Extraction

The MySpace module in [`holehe/modules/social_media/myspace.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/myspace.py) demonstrates extracting a CSRF token from a hidden input field. While it uses string splitting for precision, it falls back to BeautifulSoup patterns for other extractions.

```python

# Example: MySpace CSRF extraction (holehe/modules/social_media/myspace.py)

r = await client.get("https://myspace.com/signup/email", headers=headers)

# Grab the hidden CSRF token from the page

csrf_token = r.text.split('<input name="csrf" type="hidden" value="')[1].split('"')[0]
headers["Hash"] = csrf_token
response = await client.post(
    "https://myspace.com/ajax/account/validateemail",
    headers=headers,
    data={"email": email},
)

# Detect the “already used” message in the response text

if "This email address was already used" in response.text:
    out.append({"exists": True, ...})

```

### Snapchat: Attribute-Based Token Parsing

In [`holehe/modules/social_media/snapchat.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/snapchat.py), the module extracts the XSRF token and `web_client_id` from the login page using raw string splitting on the `data-xsrf` attribute. This approach avoids full DOM parsing when the token location is predictable.

```python
xsrf = req.text.split('data-xsrf="')[1].split('"')[0]

```

### Tumblr: Script Tag Analysis

The Tumblr module located at [`holehe/modules/social_media/tumblr.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/tumblr.py) uses `find_all("script")` to locate JavaScript blocks containing bearer tokens. It parses the text content of script tags to extract authentication credentials required for the login request.

```python
scripts = BeautifulSoup(getBearer.text, "html.parser").find_all("script")

```

### Odnoklassniki: Standard BeautifulSoup Patterns

[`holehe/modules/social_media/odnoklassniki.py`](https://github.com/megadose/holehe/blob/main/holehe/modules/social_media/odnoklassniki.py) showcases standard usage where the entire page is parsed and specific hidden fields are accessed via conventional BeautifulSoup method calls.

```python
root_soup = BeautifulSoup(request.content, 'html.parser')

```

## Summary

- **Centralized Parser**: All modules import `BeautifulSoup` from [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) to ensure consistent parsing behavior across the codebase.
- **Asynchronous Architecture**: `httpx.AsyncClient` handles page fetching without blocking, enabling concurrent checks against thousands of services.
- **Flexible Extraction**: Holehe employs both CSS selectors (e.g., `body.select("form input")`) and targeted string splitting depending on the complexity of the target site's HTML structure.
- **Form Emulation**: The tool reconstructs login requests by extracting hidden fields and CSRF tokens, then submitting them with the target email to trigger account-existence indicators.
- **Marker Detection**: Post-submission analysis searches for specific HTML elements (like `auth-password-missing-alert`) or JSON responses to determine registration status.

## Frequently Asked Questions

### What HTML parser does Holehe use?

Holehe uses **BeautifulSoup** with the `html.parser` engine. The parser is imported once in [`holehe/core.py`](https://github.com/megadose/holehe/blob/main/holehe/core.py) and utilized across all service modules to convert raw HTTP responses into queryable DOM objects.

### How does Holehe handle anti-CSRF tokens?

Modules extract CSRF tokens from hidden form inputs using CSS selectors or string splitting. For example, the MySpace module retrieves the token from an input field named `csrf` and passes it in the request headers as `Hash` to validate the email check request.

### Why does Holehe sometimes use string splitting instead of BeautifulSoup?

For specific tokens embedded in predictable HTML attributes—such as Snapchat's `data-xsrf` attribute—string splitting is faster and more reliable than full DOM traversal. This approach reduces parsing overhead when the exact string pattern is consistent across responses.

### How does Holehe determine if an email account exists after parsing?

After submitting the reconstructed form payload, Holehe inspects the response for known indicators. These include specific `<div>` IDs like Amazon's `auth-password-missing-alert`, JSON flags such as `hasSnapchat`, or textual markers like "This email address was already used" in the response body.