# Maven Course Scraper — Cohort Courses, Prices & Instructors (`vsekar91/maven-course-scraper`) Actor

Extract cohort-based courses from Maven.com — title, instructor, cohort dates, price, student count, ratings, description, format, and tags. Scrapes public listing and detail pages via embedded JSON (no login required).

- **URL**: https://apify.com/vsekar91/maven-course-scraper.md
- **Developed by:** [Venkatesh Sekar](https://apify.com/vsekar91) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Maven Course Scraper

Extract cohort-based courses from [Maven.com](https://maven.com) — title, instructor, cohort dates, price, student enrollment, ratings, description, format, and topic tags.

### How it works

Maven is a Next.js SSR application. Every listing and detail page embeds a `__NEXT_DATA__` JSON blob that contains the full course data — no JavaScript rendering required.

**Phase 1 — Listing:** The actor fetches the provided start URLs (e.g. `https://maven.com/courses?sort=trending`). Each listing page returns up to 99 courses server-side. The actor expands a plain `/courses` URL into all three sort variants (`trending`, `new`, `best-selling`) to maximise coverage. Course slugs are deduplicated across all listing pages.

**Phase 2 — Detail:** Each unique course detail page (`/school-slug/course-slug`) is fetched concurrently. Detail pages contain richer data: full pricing, cohort schedules, ratings, and instructor social links.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | stringList | — | Listing or category URLs (required) |
| `maxCourses` | integer | 50 | Max detail pages to fetch (0 = unlimited) |
| `maxConcurrency` | integer | 3 | Parallel detail fetches |
| `proxyConfiguration` | proxy | Apify default | Proxy for outbound requests |

**Accepted start URL formats:**
- `https://maven.com/courses` — expands to all 3 sort variants
- `https://maven.com/courses?sort=trending`
- `https://maven.com/courses?sort=new`
- `https://maven.com/courses?sort=best-selling`
- `https://maven.com/courses/ai` — category leaderboard (top 9)
- `https://maven.com/courses/product`

### Output schema (per course)

```json
{
  "url": "https://maven.com/shreyas-doshi/product-sense",
  "course_id": 9991,
  "course_slug": "product-sense",
  "school_slug": "shreyas-doshi",
  "school_name": "Shreyas Doshi",
  "school_verified": true,
  "title": "World-class Product Sense in Practice",
  "description": "...",
  "format": "full_course",
  "price_usd": 3000.0,
  "currency": "USD",
  "num_ratings": 0,
  "avg_rating": null,
  "enrolled_last_week": "28",
  "social_image_url": "https://...",
  "tags": ["Product", "Strategy", "For Product Managers"],
  "instructors": [
    {
      "name": "Shreyas Doshi",
      "headline": "Former PM leader at Stripe, Twitter, Yahoo",
      "linkedin_url": null,
      "twitter_handle": "",
      "custom_social_link": null,
      "image_url": "https://...",
      "previous_employers": ["Stripe", "Twitter"]
    }
  ],
  "next_cohorts": [
    {
      "cohort_id": 24597,
      "name": "May 2026",
      "start_date": "2026-05-02T16:00:00Z",
      "end_date": "2026-05-09T23:00:00Z",
      "max_size": null
    }
  ],
  "next_cohort_start": "2026-05-02T16:00:00Z",
  "next_cohort_end": "2026-05-09T23:00:00Z"
}
````

Courses that fail to scrape are still pushed with an `"error"` field so the overall run always produces a complete dataset.

### Notes

- Maven returns up to 99 courses per listing page server-side. The "Show more courses" button on the UI loads additional courses via JavaScript — the scraper does not execute JS, so it picks up the first page of each sort variant (~99 × 3 = ~297 unique courses before dedup).
- Category pages (e.g. `/courses/ai`) only return the top 9 leaderboard courses server-side.
- `avg_rating` is derived from `sum_ratings / num_ratings / 10` to convert Maven's internal 100-point scale to a 10-point scale. Many courses have `num_ratings = 0` if they use an external review platform (e.g. testimonial.to).
- No authentication is required. All data is publicly accessible.

# Actor input Schema

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

Maven listing or category URLs to scrape. Accepted formats: https://maven.com/courses, https://maven.com/courses?sort=trending, https://maven.com/courses?sort=new, https://maven.com/courses?sort=best-selling, https://maven.com/courses/ai (category page). The actor collects all course slugs found on each page, deduplicates, then fetches detail pages.

## `maxCourses` (type: `integer`):

Maximum number of course detail pages to fetch (after deduplication). Set to 0 for unlimited.

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

How many detail pages to fetch in parallel.

## `proxyConfiguration` (type: `object`):

Proxy used for outbound requests. Maven.com allows most datacenter IPs.

## Actor input object example

```json
{
  "startUrls": [
    "https://maven.com/courses?sort=trending",
    "https://maven.com/courses?sort=new",
    "https://maven.com/courses?sort=best-selling"
  ],
  "maxCourses": 50,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": []
  }
}
```

# 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": [
        "https://maven.com/courses?sort=trending",
        "https://maven.com/courses?sort=new",
        "https://maven.com/courses?sort=best-selling"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("vsekar91/maven-course-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": [
        "https://maven.com/courses?sort=trending",
        "https://maven.com/courses?sort=new",
        "https://maven.com/courses?sort=best-selling",
    ] }

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

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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": [
    "https://maven.com/courses?sort=trending",
    "https://maven.com/courses?sort=new",
    "https://maven.com/courses?sort=best-selling"
  ]
}' |
apify call vsekar91/maven-course-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=vsekar91/maven-course-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Maven Course Scraper — Cohort Courses, Prices & Instructors",
        "description": "Extract cohort-based courses from Maven.com — title, instructor, cohort dates, price, student count, ratings, description, format, and tags. Scrapes public listing and detail pages via embedded JSON (no login required).",
        "version": "0.1",
        "x-build-id": "Xqd0HlgD2CXe0sdE7"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/vsekar91~maven-course-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-vsekar91-maven-course-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/vsekar91~maven-course-scraper/runs": {
            "post": {
                "operationId": "runs-sync-vsekar91-maven-course-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/vsekar91~maven-course-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-vsekar91-maven-course-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "Start URLs",
                        "type": "array",
                        "description": "Maven listing or category URLs to scrape. Accepted formats: https://maven.com/courses, https://maven.com/courses?sort=trending, https://maven.com/courses?sort=new, https://maven.com/courses?sort=best-selling, https://maven.com/courses/ai (category page). The actor collects all course slugs found on each page, deduplicates, then fetches detail pages.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxCourses": {
                        "title": "Max courses",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Maximum number of course detail pages to fetch (after deduplication). Set to 0 for unlimited.",
                        "default": 50
                    },
                    "maxConcurrency": {
                        "title": "Max concurrent fetches",
                        "minimum": 1,
                        "maximum": 10,
                        "type": "integer",
                        "description": "How many detail pages to fetch in parallel.",
                        "default": 3
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Proxy used for outbound requests. Maven.com allows most datacenter IPs.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": []
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
