# Internshala Scraper - Internships & Fresher Jobs with Salary (`mochiboo/internshala-jobs-internships-scraper`) Actor

Internshala internships and fresher jobs (no login): title, company, stipend or salary numbers, location, duration, start and apply-by dates and the listing description, from the search and listing page shapes listed in the README. E-mails and phone numbers in text are removed.

- **URL**: https://apify.com/mochiboo/internshala-jobs-internships-scraper.md
- **Developed by:** [mochi](https://apify.com/mochiboo) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.40 / 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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Internshala Scraper - internships and fresher jobs with stipend/salary, deadline and description

Turn Internshala listing pages into a clean table: **internships and fresher jobs with the stipend or salary as numbers, the apply-by date, number of openings, skills, perks, the job description and the company website.** Paste a category, city, work-from-home, part-time or fresher-jobs listing page (or single listing URLs) and get one row per listing. Public pages only, no login, no cookies, no applying.

### What you get

- **The Internshala listing pages listed under Input**: the plain all-internships, all-jobs and all-fresher-jobs pages, category and city pages, work-from-home and part-time pages, fresher-jobs pages, and filter pages with a second part. Internships and jobs in one Actor; the Actor follows "Next" until the last page.
- **Pay as numbers** (`salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`) and the **exact posting date** (`datePosted`, `applyBy`) when Internshala publishes them. Internshala publishes this structured data for only part of its listings. In our checks on the Apify platform on 21 Oct 2026 (140 listings from three pages: Python internships, Pune internships, Pune fresher jobs) 55 in 100 listings had pay numbers and 70 in 100 had the exact dates; the share differed by page, from 48 to 65 in 100 for pay numbers and from 57 to 90 in 100 for dates. The pay as shown on the page (`payText`, for example `₹ 5,000 - 8,000 /month`) is always there.
- **Detail** per listing: the "About the internship/job" text, start date, apply-by date, openings, skills, perks, company website and "about the company". The separate "Who can apply", "Other requirements" and "Additional information" sections of a listing are not included.
- **Cheap**: pay per listing with the detail page included. One row costs the same with or without the details.

### Input

| Field | What it does |
|---|---|
| `searchUrls` | Internshala listing pages, in the shapes listed below the table. A `page-N` part or a query string is ignored: the Actor always starts from page 1 and follows "Next". |
| `listingUrls` | Single listings: `https://internshala.com/internship/detail/<name><number>` or `https://internshala.com/job/detail/<name><number>`. The row is built from that page alone. |
| `includeDetails` | Default `true`: opens each listing for the details (one extra request per listing). `false` returns the list-page fields only, much faster. |
| `maxResults` | Listings per run: 200 when you leave it out of an API call, hard cap 5,000. The Console form starts with 20, a quick and cheap first run. |
| `proxyConfiguration` | Apify datacenter proxy by default. Residential proxies are not needed. |

Accepted `searchUrls` addresses (they may start with `https://`, `http://`, `www.` or nothing, and may carry a query string or a `#` part):

- category, city, work-from-home and part-time pages: `https://internshala.com/internships/marketing-internship/`, `https://internshala.com/internships/work-from-home-internships/`, `https://internshala.com/jobs/jobs-in-pune/`
- fresher-jobs pages: `https://internshala.com/fresher-jobs/jobs-in-pune/`
- the plain pages: `https://internshala.com/internships/`, `https://internshala.com/jobs/`, `https://internshala.com/fresher-jobs/`
- filter pages with a second part: `https://internshala.com/internships/work-from-home-internships/part-time-true/`, `https://internshala.com/jobs/jobs-in-pune/work-from-home/`

Anything else (for example `internshala.com/student/...`, an address with three or more path parts, another website) is not read.

Fill `searchUrls` or `listingUrls` (or both). If neither holds a usable address, the run fails at once with a one-line message that lists the accepted shapes (and names the first unusable address, if you gave one), and nothing is charged. Unusable addresses next to usable ones are skipped and listed in the `FAILURES` record with the status `unsupported_input`.

### Output

One row per listing (duplicates across your URLs are removed, the first one wins). Fields, in this order:

| Field | Meaning |
|---|---|
| `listingId` | Internshala's id of the listing |
| `type` | `internship` or `job` |
| `url` | Link to the listing |
| `title`, `company` | Role title and company name (the NGO tag Internshala shows next to some company names is not part of it) |
| `companyLogoUrl` | Logo link, `null` when the company has no logo |
| `companyWebsite` | Company website (details on) |
| `activelyHiring` | `true` when the card shows the "Actively hiring" badge |
| `locations` | Locations as listed, for example `["Pune"]` or `["Work from home"]`; when a listing has several cities the list page can show them as one text, for example `["Hyderabad, Thane, Bangalore"]` |
| `locationNote` | Extra note on the location, for example `Hybrid` |
| `cities`, `regions`, `country` | City, state and country code from Internshala's structured data, when published |
| `payText` | Stipend or salary exactly as shown, for example `₹ 5,000 - 8,000 /month` |
| `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod` | Pay as numbers, for example `5000`, `8000`, `INR`, `MONTH` (period for example `MONTH`, `WEEK` or `YEAR`), when published |
| `durationText` | Internship duration, for example `6 Months` |
| `experienceText`, `experienceMonths` | Experience for jobs as shown, and as a number of months when published |
| `startDateText` | Start date as shown, for example `Immediately` |
| `applyByText`, `applyBy` | Apply-by date as shown (`10 Nov' 26`) and as `YYYY-MM-DD` when published |
| `datePosted`, `postedText` | Exact posting date `YYYY-MM-DD` when published, and the relative text from the list page (`1 week ago`) |
| `openings` | Number of openings |
| `skills`, `perks` | Skills required and perks (certificate, flexible hours, ...) |
| `partTime` | `true` when the card is marked "Part time" |
| `jobOfferText` | For example `Job offer upto ₹ 6LPA post internship` |
| `earlyApplicant` | `true` when the card shows "Be an early applicant" |
| `employmentType`, `industry`, `category` | From Internshala's structured data, when published (for example `INTERN, PART_TIME`) |
| `snippet` | The short description shown on the list page |
| `description`, `aboutCompany` | The "About the internship/job" text and the company description (details on) |
| `jsonLd` | `true` when the listing had Internshala's structured data, `false` when it did not, `null` when details were not read |
| `detailStatus` | `ok`, `failed` (the detail page could not be read; the list-page fields are kept) or `not_requested` |
| `sourceUrl` | The listing page or listing URL that produced the row |
| `scrapedAt` | When the row was collected (ISO time) |

Fields that exist only when Internshala publishes them (the structured data) are `null` otherwise; with `includeDetails` off every detail field is `null` or `[]` (the list page's `skills` stay). A single listing URL row has no list-page fields (`snippet`, `postedText`, `durationText`, `experienceText`, `jobOfferText`, `companyLogoUrl`, `locationNote` are `null`, and `activelyHiring`, `earlyApplicant`, `partTime` are `null` because they are only known from the list page).

#### Run summary

Every run that starts reading Internshala writes `RUN_SUMMARY` to the key-value store: `complete`, `terminationReason` (`finished`, `max_results`, `charge_limit`, `time_budget`, `blocked` or `request_failed`), `rowsPushed`, `searchUrls`, `pages`, `details`, `detailFailed`, `jsonLdRows` and `requests`. The `FAILURES` record lists every URL that could not be used and why (`unsupported_input`, `no_listings`, `not_found`, `redirected`, `detail_unparsed`, `request_failed`, `blocked`). A run that fails because its input holds nothing usable to read writes `FAILURES` only, no `RUN_SUMMARY`.

If the Apify platform moves a run to another server, the Actor carries on where it stopped: listings already in the dataset are not written (or charged) again, and the summary gets a `restarts` count. After such a restart `rowsPushed` still equals the number of rows in the dataset; `requests`, `pages` and the `FAILURES` list are counted from the last saved position, so they can be a little off for that run.

### Speed, big runs and limits

- The Actor is polite: **one request at a time, one every 2 seconds at most**, never faster. Measured on the Apify platform at 512 MB memory: with details a listing took 3.3 to 3.8 seconds in three runs on 21 Oct 2026 and 3.8 to 4.4 seconds on 20 Oct (6.5 seconds in one slow hour), so plan on about 4 seconds: 50 listings take about 3 to 4 minutes and the default 200 about 11 to 15 minutes. Without details a list page took about 6.5 seconds (400 listings from 10 pages in 65 seconds on 21 Oct) and adds about 40 new listings (neighbouring pages repeat a few), so 1,000 listings take about 3 minutes. One listing page address is followed for at most 100 pages (about 4,000 listings); give several addresses for more.
- The 5,000 cap with details would take about 6 hours: raise the run timeout, or turn `includeDetails` off. The default 1-hour timeout fits about 800 to 1,000 listings with details. A run that is about to hit its timeout stops cleanly, keeps every row, and says `time_budget` in the summary.
- If Internshala answers with an access refusal (HTTP 403, 429, any other 4xx except "not found", or a challenge page), the Actor **stops at once**: rows already collected are kept, nothing is retried and no workaround is tried. The summary says `blocked`. If that happens before any row, the run fails with a message.
- Only public pages are read. The Actor does not collect applicant counts (Internshala shows them on its public pages), candidate data or recruiter contact details: **e-mail addresses and phone numbers that appear in descriptions, snippets and company texts are replaced** with `[email redacted]` and `[phone redacted]` (international and Indian mobile formats).
- Internshala is an India-focused board: stipends and salaries are mostly in INR and the listings are mostly in India.
- Redirects are never followed. An address that does not exist on Internshala is answered with a redirect to its main listing page; the Actor then returns no rows for it and lists it in `FAILURES` as `redirected` (with the `Location`), and nothing is charged.
- Page overlap is handled: Internshala's page 2 can repeat listings of page 1, each listing becomes one row.

### Price

Pay per result, at the rate shown in the pricing panel of this page, plus a very small per-run start fee. You are charged only for the results delivered.

Unsupported inputs, pages with no listings and refused or failed listing pages produce no rows and are not charged. If a listing's detail page cannot be read or is refused, that listing is still returned with its list-page fields (`detailStatus: failed`) and counts as a result; a refusal also ends the run (see above).

### Use cases

Internship and fresher-job market data, stipend benchmarks by skill or city, campus hiring pipelines, job aggregators and alerts (schedule the Actor daily), salary research for India, lists of hiring companies (company names and websites only).

### Notes

Use the data in line with Internshala's terms and the law that applies to you. The Actor reads only what Internshala shows to any visitor.

Keywords: internshala scraper, internshala jobs, internshala internships, india internships, fresher jobs india, internship data, stipend data, job scraper india, campus hiring, internshala api.

# Actor input Schema

## `searchUrls` (type: `array`):

Copy a listing page address from internshala.com: a category, city, work-from-home or part-time page such as https://internshala.com/internships/python-django-internship/ or https://internshala.com/jobs/jobs-in-pune/, a fresher-jobs page such as https://internshala.com/fresher-jobs/jobs-in-pune/, or the plain /internships/, /jobs/ and /fresher-jobs/ pages. A page-N part or a query string is ignored. Fill this field or the single listing field below.

## `listingUrls` (type: `array`):

Single listings: internshala.com/internship/detail/... or internshala.com/job/detail/... Fill this field or the listing pages field above.

## `includeDetails` (type: `boolean`):

Adds description, apply-by date, openings, perks, company website and salary numbers. One extra request per listing.

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

How many listings to collect, from 1 to 5000. An API call that leaves this field out gets up to 200; the Console form starts at 20, a quick and cheap first run.

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

Apify datacenter proxy by default. Residential proxies are not needed.

## Actor input object example

```json
{
  "searchUrls": [
    "https://internshala.com/internships/python-django-internship/",
    "https://internshala.com/jobs/python-django-jobs/"
  ],
  "includeDetails": true,
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One row per Internshala internship or job: pay as text and as numbers, apply-by date, openings, perks, skills, description and company website.

## `runSummary` (type: `string`):

What the run did and how it ended (the RUN_SUMMARY record in the default key-value store).

# 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 = {
    "searchUrls": [
        "https://internshala.com/internships/python-django-internship/",
        "https://internshala.com/jobs/python-django-jobs/"
    ],
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("mochiboo/internshala-jobs-internships-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 = {
    "searchUrls": [
        "https://internshala.com/internships/python-django-internship/",
        "https://internshala.com/jobs/python-django-jobs/",
    ],
    "maxResults": 20,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("mochiboo/internshala-jobs-internships-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 '{
  "searchUrls": [
    "https://internshala.com/internships/python-django-internship/",
    "https://internshala.com/jobs/python-django-jobs/"
  ],
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call mochiboo/internshala-jobs-internships-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mochiboo/internshala-jobs-internships-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/Ua5oBVZUnkRhbMabm/builds/EMwKZOKXgjOLseYtJ/openapi.json
