# WhistleOut Scraper $0.0015💰 | Phone Plans | Broadband (`ahmed_jasarevic/whistleout-scraper`) Actor

Monitor cell phone plan and internet deal prices, plus carrier plan data, from WhistleOut.com. Extract structured phone plan comparison data for price monitoring, telecom market research, and building plan comparison databases - no official API required.

- **URL**: https://apify.com/ahmed\_jasarevic/whistleout-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## WhistleOut Scraper — Cell Phone Plan & Internet Deal Data

Scrape structured **cell phone plan comparison** and **internet/broadband deal** data from **WhistleOut.com** to power phone plan price monitoring, telecom market research, and plan comparison databases — no official API needed.

### Main Use Cases

- **Phone plan price monitoring** — track cell phone and internet plan pricing over time across carriers
- **Cell phone plan comparison** — build structured, sortable datasets of contracts, speeds, and data allowances
- **Broadband / internet deal tracking** — capture bundle prices, speed tiers, and promotional deals
- **Telecom market research** — analyze carrier, supplier, and MVNO plan offerings at scale
- **Carrier & MVNO rate intelligence** — understand how carriers position plans by price, data, and speed
- **Telecom plan database creation** — feed comparison engines, analytics dashboards, and AI agents with live plan data

### Build Telecom Plan Databases Without an Official API

WhistleOut compares hundreds of cell phone plans and internet deals across US carriers big and small. There is no public programmatic API for its comparison tables — this Actor gives you the structured plan data directly.

It uses `CheerioCrawler` (fast plain-HTTP parsing, no heavy browser) with the **Apify proxy** and automatic **session rotation**. When a page gets blocked, Crawlee rotates to a fresh proxy IP and retries, which is how this Actor gets through WhistleOut's Cloudflare protection to return real plan rows.

### How It Works

1. You provide WhistleOut pages to scrape (defaults to the CellPhones and Internet comparison listings).
2. The Actor crawls those pages — and same-domain CellPhones/Internet listings — bounded by your `maxRequestsPerCrawl` limit.
3. Each `tr.content-row` plan row is parsed into a structured record.
4. Every plan is pushed to the dataset with its carrier, plan name, price, data, speed, features, deal, and plan links.

### Input

The Actor accepts the following input fields (all optional):

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `startUrls` | array | No | `https://www.whistleout.com/CellPhones`, `https://www.whistleout.com/Internet` | WhistleOut pages to scrape. Override to target specific category or carrier listing pages. |
| `maxRequestsPerCrawl` | integer | No | `100` | Maximum number of pages to scrape. `0` = unlimited. |
| `maxConcurrency` | integer | No | `10` | Maximum number of pages scraped in parallel (1–50). |

### Output

Each dataset item is one plan found in a WhistleOut comparison table, with these fields:

| Field | Type | Description |
|---|---|---|
| `supplier` | string | Carrier / supplier name (e.g. Verizon, T-Mobile, AT\&T MVNOs) |
| `productName` | string | Plan or product name |
| `totalPrice` | string | Total price as displayed by WhistleOut |
| `priceText` | string | Raw product-price text from the row |
| `dataAmount` | string | Included data allowance (e.g. "Unlimited", "10GB") |
| `speed` | string | Plan / internet speed (e.g. download speed, 5G) |
| `features` | array | List of plan features parsed from the row |
| `deal` | string | Promotional deal / offer text, when present |
| `viewPlanUrl` | string | Absolute link to view the plan on WhistleOut |
| `logoUrl` | string | Carrier logo image URL |
| `url` | string | Source WhistleOut page the plan was scraped from |

### Example Input

```json
{
  "startUrls": [
    { "url": "https://www.whistleout.com/CellPhones" },
    { "url": "https://www.whistleout.com/Internet" }
  ],
  "maxRequestsPerCrawl": 100,
  "maxConcurrency": 10
}
```

### Example Output

```json
[
  {
    "url": "https://www.whistleout.com/CellPhones",
    "supplier": "Verizon",
    "productName": "Verizon Unlimited Plus",
    "totalPrice": "$80.00/mo",
    "priceText": "$80.00/mo",
    "dataAmount": "Unlimited",
    "speed": "5G UW",
    "features": ["Unlimited talk & text", "30GB premium hotspot", "Disney+ included"],
    "deal": "Exclusive online offer",
    "viewPlanUrl": "https://www.whistleout.com/...",
    "logoUrl": "https://www.whistleout.com/.../verizon-logo.png"
  }
]
```

### Integrations & Automation

- **Apify API** — call this Actor programmatically from any app or script.
- **Webhooks** — trigger downstream pipelines each time a run finishes.
- **Zapier / Make** — connect plan data to spreadsheets, databases, and analytics tools.

Because telecom plans repricing happens frequently, the strong default is a **recurring schedule** (e.g. a **daily or weekly** task) so your price-monitoring dataset stays current — the same cadence WhistleOut itself recommends for keeping comparisons accurate.

### Related Actors

- [uSwitch Scraper — UK Broadband Deals](https://apify.com/crawlerbros/uswitch-scraper) — broadband deal comparison data from uSwitch.co.uk
- [uSwitch broadband / BroadbandGenie Scraper](https://apify.com/crawlerbros/broadbandgenie-scraper) — UK broadband deals, speeds, and contract terms
- [Check24 Scraper — German Comparison Plans & Prices](https://apify.com/studio-amba/check24-scraper) — mobile & DSL comparisons in Germany

### FAQ

#### Why use this actor instead of an official WhistleOut API?

WhistleOut does not offer a public API for its comparison tables. Its published embeddable widgets must be used on your own site and still don't give you a clean, queryable dataset. This Actor returns the actual plan rows (carrier, plan, price, data, speed, features, links) as structured JSON you can store and analyze.

#### Is there a WhistleOut API or a WhistleOut API alternative?

There is no public WhistleOut API for plan data. If you need WhistleOut's US phone/internet comparison data as structured records, this Actor is the practical route — it fetches the public CellPhones and Internet listing pages and parses them into a dataset.

#### What is the best way to compare cell phone plans in bulk?

Run this Actor over WhistleOut's CellPhones listing (the default), then sort and filter the resulting dataset by `totalPrice`, `dataAmount`, and `speed`. Scheduling the task keeps the comparison set current as plans reprice.

#### How can I get cell phone and internet plan pricing data without an official API?

Use a scraper. This Actor pulls the public comparison pages from WhistleOut.com, parses each `tr.content-row` into fields like `supplier`, `productName`, `totalPrice`, `dataAmount`, and `speed`, and outputs them to the dataset for export as JSON, CSV, or Excel.

#### Which carriers does WhistleOut compare?

WhistleOut compares plans from over 40 carriers in the US, including the major networks and their prepaid/MVNO brands. The `supplier` field in the output records the carrier for each plan.

#### How often should I re-scrape to keep a comparison database current?

Telecom plans reprice frequently. A daily or weekly recurring task is the recommended cadence, so your dataset reflects current plan prices, data, and promotional deals.

### For AI Agents & LLM Apps

**Purpose:** Returns one structured record per cell phone or internet plan found in a WhistleOut.com comparison listing, including carrier, plan name, price, data, speed, and features.

**Minimal working input:**

```json
{
  "startUrls": [{ "url": "https://www.whistleout.com/CellPhones" }],
  "maxRequestsPerCrawl": 10
}
```

**Output fields (comma-separated):**
`supplier, productName, totalPrice, priceText, dataAmount, speed, features, deal, viewPlanUrl, logoUrl, url`

**Behaviors an agent should know:**

- `startUrls` defaults to the CellPhones and Internet listings if omitted.
- `maxRequestsPerCrawl` caps total pages (default 100; `0` = unlimited) — this bounds cost, so set it deliberately.
- `maxConcurrency` controls parallelism (default 10, max 50).
- The Actor is a `CheerioCrawler` (HTTP + HTML, no browser); the Apify proxy and session rotation are used to get past the site's bot protection.
- A plan row is only pushed when real `tr.content-row` plan data is found; pages without plan rows return a fallback record with a `note` instead.
- Only same-domain `CellPhones`/`Internet` listing URLs are followed.

**Billing model:** pay-per-event — `Actor Start` $0.00005/event plus `result` $0.0015 per dataset item.

### Legal & Compliance Disclaimer

This Actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by WhistleOut**. It only accesses **publicly available** WhistleOut.com listing pages using real browser-like headers and a rotating proxy — it does not bypass login walls, solve CAPTCHAs, or access non-public content.

Users are responsible for their own use: review and comply with WhistleOut's Terms of Use and applicable laws (including US federal and state data regulations) before scraping at scale, and use reasonable, respectful request volumes.

### SEO Keywords

whistleout scraper, phone plan price monitoring, cell phone plan comparison, internet plan comparison, broadband deal tracking, telecom market research, phone plan data, cell phone carrier comparison, whistleout data extraction, whistleout api alternative, mobile plan pricing data, mvno plan data, telecom plan database, carrier rate research, compare cell phone plans, internet deal data, prepaid plan data, phone plan price tracking, telecom pricing data, carrier plan intelligence

# Actor input Schema

## `startUrls` (type: `array`):

WhistleOut pages to scrape. Defaults to cell phone and internet plan pages.

## `maxRequestsPerCrawl` (type: `integer`):

Maximum number of pages to scrape (0 = unlimited).

## `maxConcurrency` (type: `integer`):

Maximum number of pages scraped in parallel.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.whistleout.com/CellPhones"
    },
    {
      "url": "https://www.whistleout.com/Internet"
    }
  ],
  "maxRequestsPerCrawl": 100,
  "maxConcurrency": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.whistleout.com/CellPhones"
        },
        {
            "url": "https://www.whistleout.com/Internet"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/whistleout-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": [
        { "url": "https://www.whistleout.com/CellPhones" },
        { "url": "https://www.whistleout.com/Internet" },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/whistleout-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.whistleout.com/CellPhones"
    },
    {
      "url": "https://www.whistleout.com/Internet"
    }
  ]
}' |
apify call ahmed_jasarevic/whistleout-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/whistleout-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/HuJ98UzzXQPXmdSyp/builds/salDX7A0QJy3onC4q/openapi.json
