# Udemy Course Scraper (`khadinakbar/udemy-course-scraper`) Actor

Scrape Udemy courses by keyword search or course URL — price, rating, reviews, enrollment, instructor, level, language.

- **URL**: https://apify.com/khadinakbar/udemy-course-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Developer tools, MCP servers, Lead generation
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 course scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## 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

## Udemy Course Scraper

Scrape Udemy courses two ways — **keyword search** across the catalog, or **deep detail by course URL**. One flat JSON record per course: price, rating, review count, enrollment, instructor, level, language, last-updated, and more. HTTP-only, no login, no cookies. MCP-ready for AI agents.

### What you get

| Field | Description |
|---|---|
| `courseId` | Udemy numeric course ID |
| `title` | Course title |
| `url` | Course landing-page URL |
| `headline` | Short course headline |
| `isPaid` | Paid vs free |
| `price` / `priceCurrency` | Listed price string + currency |
| `rating` | Average star rating |
| `numReviews` | Number of ratings/reviews |
| `numSubscribers` | Enrolled students |
| `numPublishedLectures` | Lecture count |
| `contentInfo` | Total content length (e.g. "52 total hours") |
| `level` | Beginner / Intermediate / Expert / All |
| `category` / `subcategory` | Udemy taxonomy |
| `language` | Course language |
| `lastUpdated` / `createdAt` | ISO dates |
| `instructorName` / `instructorJobTitle` / `instructorUrl` | Lead instructor |
| `imageUrl` | Course thumbnail |
| `objectives` | "What you'll learn" bullet list |

### When to use it

- **Course-market research** — what topics exist, how saturated, at what price/rating.
- **Affiliate selection** — surface highest-rated / most-reviewed courses in a niche.
- **Pricing & competitive analysis** — track price and rating of competitor courses by URL.
- **Catalog enrichment** — turn a list of course URLs into a structured dataset.

Not for: course video, lecture content, or transcripts.

### Input

Provide **at least one** of:

- **Search queries** — keywords like `python for beginners`, `excel`. Each is paginated up to **Max results**.
- **Course URLs** — full links like `https://www.udemy.com/course/the-complete-javascript-course/`. Each returns one deep record.

Optional: **Max results per query** (default 50), **Language filter** (`en`, `es`, ...), **Sort order** (relevance / highest-rated / most-reviewed / newest).

```json
{
  "searchQueries": ["python for beginners"],
  "startUrls": ["https://www.udemy.com/course/the-complete-javascript-course/"],
  "maxResults": 50,
  "sortBy": "highest-rated"
}
````

### Pricing — Pay Per Event

| Event | Price |
|---|---|
| Actor start | $0.00005 |
| Course scraped | **$0.003 per course** |

A 50-result search costs about **$0.15**. Pay-per-usage (compute + proxy) is also available — choose at run time.

### How it works

Requests go over **Apify Residential US** proxies with a Chrome-impersonated TLS client (impit) to clear Cloudflare. Course data comes from Udemy's `api-2.0` endpoints; for course-detail-by-URL, the actor falls back to the course landing-page structured data (`ld+json`) when the API is rate-gated, so detail mode keeps returning core fields (title, rating, reviews, category, instructor) even under pressure.

### MCP / AI agents

Exposed as `apify--udemy-course-scraper` in Apify MCP. Single keyword or URL in, flat JSON out — a natural tool call for course research, affiliate, and pricing agents.

### Legal

Scrapes only publicly available course data. Respect Udemy's Terms of Service and applicable laws. Use the data for research, analysis, and lawful commercial purposes. You are responsible for your own compliance.

# Actor input Schema

## `searchQueries` (type: `array`):

Keyword searches run against the Udemy catalog, one record per matching course (e.g. 'python for beginners', 'excel'). Each query is paginated up to maxResults. Leave empty if you only want to scrape specific course URLs. NOT a course URL — put full course links in 'Course URLs' instead.

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

Full Udemy course landing-page URLs to scrape in detail (e.g. 'https://www.udemy.com/course/the-complete-javascript-course/'). Each returns one deep record. Leave empty if you only want keyword search. NOT a search keyword — use 'Search queries' for that.

## `maxResults` (type: `integer`):

Maximum number of courses to return per search query (course URLs are always all scraped). Defaults to 50. Range 1-1000. Higher values cost more and run longer at $0.003 per course returned.

## `language` (type: `string`):

Restrict search results to courses in a single language by ISO code (e.g. 'en', 'es', 'de'). Applies only to search queries, not course URLs. Leave empty for all languages. NOT a country code — it filters course content language.

## `sortBy` (type: `string`):

Order of search results. 'relevance' is Udemy default; 'highest-rated' surfaces top-rated courses; 'most-reviewed' surfaces popular ones; 'newest' surfaces recent ones. Applies only to search queries.

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

Proxy settings. Udemy requires Apify Residential US to pass Cloudflare and the api-2.0 IP gate — this is the enforced default. Override only if you know what you are doing.

## Actor input object example

```json
{
  "searchQueries": [
    "excel",
    "digital marketing"
  ],
  "startUrls": [
    "https://www.udemy.com/course/the-complete-javascript-course/"
  ],
  "maxResults": 50,
  "language": "en",
  "sortBy": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `courses` (type: `string`):

All scraped Udemy course records.

# 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 = {
    "searchQueries": [
        "python for beginners"
    ],
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/udemy-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 = {
    "searchQueries": ["python for beginners"],
    "maxResults": 50,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/udemy-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 '{
  "searchQueries": [
    "python for beginners"
  ],
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call khadinakbar/udemy-course-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Udemy Course Scraper",
        "description": "Scrape Udemy courses by keyword search or course URL — price, rating, reviews, enrollment, instructor, level, language.",
        "version": "1.0",
        "x-build-id": "OhVyhjoDzlG7Qi4WC"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/khadinakbar~udemy-course-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-khadinakbar-udemy-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/khadinakbar~udemy-course-scraper/runs": {
            "post": {
                "operationId": "runs-sync-khadinakbar-udemy-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/khadinakbar~udemy-course-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-khadinakbar-udemy-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",
                "properties": {
                    "searchQueries": {
                        "title": "Search queries",
                        "type": "array",
                        "description": "Keyword searches run against the Udemy catalog, one record per matching course (e.g. 'python for beginners', 'excel'). Each query is paginated up to maxResults. Leave empty if you only want to scrape specific course URLs. NOT a course URL — put full course links in 'Course URLs' instead.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "startUrls": {
                        "title": "Course URLs",
                        "type": "array",
                        "description": "Full Udemy course landing-page URLs to scrape in detail (e.g. 'https://www.udemy.com/course/the-complete-javascript-course/'). Each returns one deep record. Leave empty if you only want keyword search. NOT a search keyword — use 'Search queries' for that.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxResults": {
                        "title": "Max results per query",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of courses to return per search query (course URLs are always all scraped). Defaults to 50. Range 1-1000. Higher values cost more and run longer at $0.003 per course returned.",
                        "default": 50
                    },
                    "language": {
                        "title": "Course language filter",
                        "type": "string",
                        "description": "Restrict search results to courses in a single language by ISO code (e.g. 'en', 'es', 'de'). Applies only to search queries, not course URLs. Leave empty for all languages. NOT a country code — it filters course content language."
                    },
                    "sortBy": {
                        "title": "Search sort order",
                        "enum": [
                            "relevance",
                            "highest-rated",
                            "most-reviewed",
                            "newest"
                        ],
                        "type": "string",
                        "description": "Order of search results. 'relevance' is Udemy default; 'highest-rated' surfaces top-rated courses; 'most-reviewed' surfaces popular ones; 'newest' surfaces recent ones. Applies only to search queries.",
                        "default": "relevance"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Proxy settings. Udemy requires Apify Residential US to pass Cloudflare and the api-2.0 IP gate — this is the enforced default. Override only if you know what you are doing.",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "US"
                        }
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
