Metadata-Version: 2.4
Name: NullGazeX
Version: 2.2.1
Summary: NullGazeX — a highly resilient image downloading library that handles DPI/SNI configurations, Cloudflare challenges, TLS fingerprinting, and hotlinking protections.
Home-page: https://github.com/batal/NullGazeX
Author: Batal
Author-email: batal@example.com
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Multimedia :: Graphics
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25.0
Requires-Dist: curl_cffi>=0.5.0
Provides-Extra: browser
Requires-Dist: DrissionPage>=4.0.0; extra == "browser"
Provides-Extra: full
Requires-Dist: curl_cffi>=0.5.0; extra == "full"
Requires-Dist: DrissionPage>=4.0.0; extra == "full"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# Specter

Specter is a highly resilient, high-performance Python library designed for robust image downloading. It implements a multi-tier fallback pipeline to address restrictive network configurations, anti-scraping protections (Cloudflare), TLS fingerprinting, and hotlinking restrictions.

---

## Features

- **Multi-Tier Fallback Pipeline**: Sequentially attempts multiple download strategies (Direct, DPI-Resilient proxy, Browser-rendering, and Cache-proxy) to ensure successful retrieval.
- **DPI Resilience via ClientHello Segmentation**: Implements a local loopback proxy that segments the TLS ClientHello packet, helping resolve network connection limitations.
- **Domain Strategy Caching**: Thread-safe caching mechanism that stores the successful strategy for each domain, skipping slow timeouts and retries on subsequent requests.
- **Thread-Local Connection Pooling**: Reuses TCP and TLS connections via Keep-Alive sessions per thread to achieve sub-100ms request times.
- **Parallel Batch Downloading**: Supports concurrent downloading of multiple images using a built-in ThreadPoolExecutor.
- **Headless Browser Fallback**: Integrates headless Chromium rendering (via DrissionPage) as a fallback to extract images from canvas elements or screenshots.

---

## Installation

### Standard Installation
```bash
pip install NullGazeX
```

### Full Installation (with Headless Browser support)
```bash
pip install NullGazeX[full]
```

---

## Quick Start

### 1. Download a Single Image
```python
from specter import download_image

# Download an image with automatic header and referrer matching
download_image(
    url="https://example.com/images/photo.jpg",
    output_path="outputs/photo.jpg",
    verbose=True
)
```

### 2. Concurrent Batch Downloading
To download multiple images concurrently at maximum speed, use the batch downloading interface:
```python
from specter import download_images

# Define a list of targets (url, output_path)
targets = [
    ("https://example.com/img1.jpg", "outputs/img1.jpg"),
    ("https://example.com/img2.jpg", "outputs/img2.jpg"),
    ("https://example.com/img3.jpg", "outputs/img3.jpg")
]

# Run concurrent downloads (default max_workers is 20)
results = download_images(targets, max_workers=10, verbose=True)

for i, res in enumerate(results):
    if isinstance(res, Exception):
        print(f"Failed to download image {i+1}: {res}")
    else:
        print(f"Successfully saved to: {res}")
```

### 3. Advanced Custom Configuration
You can customize headers or use the object-oriented API directly:
```python
from specter import ImageDownloader

downloader = ImageDownloader(verbose=True)

custom_headers = {
    "Referer": "https://custom-referer.com/",
    "Cookie": "session_token=xyz123"
}

# Download using the custom downloader instance
downloader.download(
    url="https://example.com/protected/image.png",
    output_path="outputs/image.png",
    headers=custom_headers
)
```

---

## Technical Specifications & Strategies

| Tier | Strategy | Description | Recommended Case |
| :--- | :--- | :--- | :--- |
| **1** | **Direct Request** | Sends a standard HTTP GET with dynamically generated browser headers. | Open networks and unrestricted servers. |
| **2** | **DPI Resilience (Split Proxy)** | Routes request through a local background proxy that segments the TLS handshake packets to handle strict filters. | ISP-level filters and strict configurations. |
| **3** | **Headless Browser** | Spawns a headless Chromium instance to render the page and extract the image canvas or take screenshots. | Cloudflare Turnstile or JS challenges. |
| **4** | **Weserv Proxy Fallback** | Routes requests through a high-availability public image cache proxy. | General availability fallbacks. |

---

## License

This project is licensed under the MIT License. See [LICENSE](LICENSE) for details.
