# Saramin Scraper — South Korea Job Ads & Employers (`logiover/saramin-scraper`) Actor

Scrape vacancies from Saramin, South Korea's largest job board: title, hiring company with profile link, location, required experience and education, employment type, job functions and deadline. Keyless, no login. JSON, CSV or Excel.

- **URL**: https://apify.com/logiover/saramin-scraper.md
- **Developed by:** [Logiover](https://apify.com/logiover) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 29 total users, 8 monthly users, 95.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

## Saramin Scraper — South Korea Job Ads & Employers

Export vacancies from **Saramin**, South Korea's largest job board — company, location, required experience and education, employment type and job functions — to JSON, CSV or Excel. Keyless, no login.

### What does Saramin Scraper do?

Saramin renders its search results server-side, so this Actor parses the result cards directly and walks the pagination. No API key, no account, no cookies.

The card packs four unrelated facts into a single unlabelled condition row: **location, required experience, required education and employment type** — and the order shifts whenever one of them is missing. Reading them positionally is exactly how a scraper ends up with `정규직` (permanent contract) sitting in a location column. This Actor classifies each value by its own Korean signature, so every column holds the right kind of fact on every row, including ads that omit education or experience entirely.

The job-functions cell also appends an "updated on" note. That note is split into its own `updatedDate` field instead of being left glued to the end of the sector list.

### Who is it for?

- **Recruitment agencies** tracking which Korean companies are hiring and where.
- **Market entrants** mapping demand before opening a Korean office.
- **B2B sales teams** using hiring activity as a growth signal.
- **Job boards and aggregators** that need a Korean feed.
- **Labour-market analysts** measuring experience and education requirements by role.

### Use cases

- List every company hiring AI or backend engineers in Gyeonggi, with company links.
- Measure what level of experience Korean employers demand for a given role.
- Track how many roles require a master's degree versus a bachelor's.
- Build a weekly feed of new postings in a job function.
- Spot the moment a target company opens its first role in a discipline.

### Why use this Actor?

- **Keyless** — nothing to sign up for.
- **16 structured fields**, with the condition row correctly split into four.
- **Experience and education requirements** as separate, filterable columns.
- **Job functions** cleaned of the trailing "updated on" note.
- **Company profile link** for every employer.
- **Honest columns** — a value only lands in a column when it matches that field's pattern.

### What data can you extract?

| Field | Type | Description |
|---|---|---|
| `jobId` | string | Saramin recruitment ID |
| `title` | string | Job title |
| `jobUrl` | string | Public ad page |
| `companyName` | string | Hiring company |
| `companyUrl` | string | Company page on Saramin |
| `location` | string | Province, city and district |
| `experienceRequired` | string | e.g. `경력10년↑`, `신입` |
| `educationRequired` | string | e.g. `대졸↑`, `석사↑` |
| `employmentType` | string | e.g. `정규직`, `계약직`, `인턴` |
| `sector` | string | Job functions, comma-separated |
| `deadlineLabel` | string | Application deadline as displayed |
| `updatedDate` | string | Date the ad was last updated |
| `badges` | string | Card badges, e.g. top-decile salary |
| `country` | string | South Korea |
| `source` | string | Always `saramin` |
| `scrapedAt` | string | Run timestamp (ISO 8601) |

#### Example output

```json
{
  "jobId": "54576019",
  "title": "LLM Developer",
  "jobUrl": "https://www.saramin.co.kr/zf_user/jobs/relay/view?rec_idx=54576019",
  "companyName": "(주)씨어스",
  "location": "경기 성남시 분당구",
  "experienceRequired": "경력 5~20년",
  "educationRequired": "석사↑",
  "employmentType": "정규직",
  "sector": "NLP(자연어처리), AIX, AWS, Azure, GCP",
  "updatedDate": "26/07/29",
  "country": "South Korea",
  "source": "saramin"
}
```

### How to use it

1. Enter a keyword — English terms work well for tech roles, Korean for everything else.
2. Optionally set a Saramin location code.
3. Set **Maximum results** and run, then export JSON, CSV or Excel.

### Input example

```json
{
  "query": "developer",
  "maxResults": 1000
}
```

### Notes and limits

- Saramin does **not** publish salary on search cards, so this Actor does not invent a salary column. Pay appears inside the ad page when the employer discloses it.
- Titles and job functions are in Korean because employers write them that way; tech roles often mix English.
- Saramin renders 40 cards per page; the Actor stops when a page returns noticeably fewer.
- This Actor exports listing cards, not full descriptions — that is what keeps bulk runs cheap. Open `jobUrl` for the full text.
- You are responsible for how you use employer data.

### FAQ

**Do I need a Saramin account?**
No. Listings are public and this Actor needs nothing from you.

**Why is there no salary field?**
Because Saramin's result cards do not carry one. Shipping an always-empty salary column would be worse than leaving it out.

**Can I search in English?**
Yes for tech and international roles; Korean keywords cover the rest of the market.

**Are experience and education always present?**
No — some ads omit them, in which case those fields are `null` rather than filled with an unrelated value.

**How am I charged?**
Pay per result — you pay for the vacancies delivered.

# Actor input Schema

## `query` (type: `string`):

Free-text search across Saramin, e.g. "developer", "디자이너" or "marketing". Leave empty to walk the newest listings.

## `location` (type: `string`):

Optional Saramin location code (loc\_mcd), e.g. 101000 for Seoul. Leave empty for all of Korea.

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

Stop after this many ads. Saramin renders 40 cards per page and the Actor walks pages until the target is met.

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

Saramin serves plain HTML; the default datacenter proxy is enough.

## Actor input object example

```json
{
  "query": "developer",
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `jobId` (type: `string`):

No description

## `title` (type: `string`):

No description

## `jobUrl` (type: `string`):

No description

## `companyName` (type: `string`):

No description

## `companyUrl` (type: `string`):

No description

## `location` (type: `string`):

No description

## `experienceRequired` (type: `string`):

No description

## `educationRequired` (type: `string`):

No description

## `employmentType` (type: `string`):

No description

## `sector` (type: `string`):

No description

## `deadlineLabel` (type: `string`):

No description

## `updatedDate` (type: `string`):

No description

## `badges` (type: `string`):

No description

## `country` (type: `string`):

No description

## `source` (type: `string`):

No description

## `scrapedAt` (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 = {
    "query": "developer",
    "location": "",
    "maxResults": 500,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/saramin-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 = {
    "query": "developer",
    "location": "",
    "maxResults": 500,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("logiover/saramin-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 '{
  "query": "developer",
  "location": "",
  "maxResults": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call logiover/saramin-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

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