# Net-Empregos Portugal Jobs Scraper: Vagas de Emprego, No Login (`getascraper/net-empregos-jobs-scraper`) Actor

Extract Portuguese job listings from net-empregos.com by district, category, or keyword. Get title, company, location, posting date, and optional full offer detail with expiry date, with correct Portuguese diacritics. Plain HTTP, no login, no JavaScript. Pay only per result, flat PPE pricing.

- **URL**: https://apify.com/getascraper/net-empregos-jobs-scraper.md
- **Developed by:** [GetAScraper](https://apify.com/getascraper) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 1 total users, 1 monthly users, 96.2% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 job offer 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

## 💼 Net-Empregos Portugal Jobs Scraper: Vagas de Emprego, No Login

<table width="100%">
<tr>
<td style="padding:24px 28px;background:#E8F5EF;border:1px solid #A9D8C2;border-top:4px solid #0B6E4F;border-radius:12px">
<span style="font-size:23px;font-weight:800;color:#1C1917;line-height:1.3">Get Portugal's job offers from Net-Empregos as clean, structured rows.</span><br>
<span style="font-size:15px;color:#57534E;line-height:1.6">Search about 60,000 active offers by keyword, place, category, and contract type. Get a daily feed of only the new offers, or a market snapshot of how many jobs are open. Export to a spreadsheet, database, or hiring dashboard.</span>
</td>
</tr>
</table>

Net-Empregos is one of Portugal's largest job boards. This Actor searches it for Lisboa, Porto, Faro, the Azores, and every other district, and saves each matching offer as one row. Schedule it and it returns only the offers that appeared since the last run. Accents stay intact, so Portuguese job titles read correctly in your output.

<table width="100%">
<tr>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #A9D8C2;border-radius:10px 0 0 10px;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#0B6E4F">Filter by place</span><br>
<span style="font-size:12px;color:#57534E">Pick several of the 28 districts and regions, or search the whole country. Add remote, part-time, or internship offers.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #A9D8C2;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#0B6E4F">Filter by sector</span><br>
<span style="font-size:12px;color:#57534E">Narrow results to any of 44 job categories, exclude words and recruitment agencies, and keep only offers from the last few days.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #A9D8C2;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#0B6E4F">Full offer details</span><br>
<span style="font-size:12px;color:#57534E">Add the description, expiry date, and what the ad states about experience, education, languages, remote work, and pay.</span>
</td>
<td style="padding:14px 12px;width:25%;background:#FFFFFF;border:1px solid #A9D8C2;border-left:none;border-radius:0 10px 10px 0;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#0B6E4F">New-offers feed</span><br>
<span style="font-size:12px;color:#57534E">Run it on a schedule and get only offers you have not seen. No login or API key needed.</span>
</td>
</tr>
</table>

### 🔍 What does this Actor do?

- **Searches live offers:** every run reads the current Net-Empregos listings, so results match what the site shows today.
- **Saves one row per offer:** ID, link, title, company, company logo, district, category, contract type, posting date, and how many days the offer has been online.
- **Returns only new offers:** switch on the new-offers option, schedule the run, and each run saves only offers this monitor has not returned before. The first run builds the baseline, so keep the search narrow enough that the first run can cover it.
- **Tracks the market:** the market snapshot mode counts open offers per district, category, and contract type, and shows the change since your previous snapshot.
- **Reads facts out of the ad text:** with full details on, rows include remote or hybrid work, years of experience, education levels, languages, and the salary when the ad states one.
- **Keeps the data honest:** a field the offer does not state is left out, never filled with a placeholder. Most Portuguese ads do not state a salary, so expect that field on only a small share of offers.

### 🧭 How it works

<table width="100%">
<tr>
<td style="padding:14px 12px;width:33%;background:#FFFFFF;border:1px solid #A9D8C2;border-radius:10px 0 0 10px;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#0B6E4F">1. Choose your search</span><br>
<span style="font-size:12px;color:#57534E">Enter keywords and pick districts, categories, and contract types. Leave any empty to widen the search.</span>
</td>
<td style="padding:14px 12px;width:33%;background:#FFFFFF;border:1px solid #A9D8C2;border-left:none;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#0B6E4F">2. Run once or on a schedule</span><br>
<span style="font-size:12px;color:#57534E">The default saves 20 offers in seconds. For a feed, turn on new offers only and schedule the run.</span>
</td>
<td style="padding:14px 12px;width:33%;background:#FFFFFF;border:1px solid #A9D8C2;border-left:none;border-radius:0 10px 10px 0;vertical-align:top">
<span style="font-size:15px;font-weight:800;color:#0B6E4F">3. Download or connect</span><br>
<span style="font-size:12px;color:#57534E">Export CSV, Excel, or JSON from the Output tab, or send each run to Slack, email, Sheets, or a webhook with Apify integrations.</span>
</td>
</tr>
</table>

### 🎯 What can I use it for?

- **Recruiters and staffing agencies:** watch which companies are hiring in a district or sector, and exclude competing agencies.
- **Job boards and alert apps:** a clean daily feed of new offers by category, with stable IDs and posting dates.
- **Market analysts and HR teams:** track open offers per district and category over time, or measure how many roles are remote.
- **Candidates and career coaches:** find recent offers that state no experience is needed, or that mention a language you speak.

### 📥 Input

| Field                                | Type          | Required | Description                                                                                                                    |
| ------------------------------------ | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| What to collect                      | enum          | No       | Job offers (default) or a market snapshot of open offers per district, category, and contract type.                            |
| Keywords                             | text          | No       | Words the offer must mention, such as a job title or skill. Leave empty to match every offer.                                  |
| Exclude words                        | list          | No       | Drop offers whose title, or description when details are on, contains any of these words.                                      |
| Districts and regions                | multi-select  | No       | Any of the 28 places the site lists, including the islands. Each choice is searched separately. Empty means the whole country. |
| Job categories                       | multi-select  | No       | Any of 44 professional categories. Empty means all.                                                                            |
| Job types                            | multi-select  | No       | Full-time, part-time, internship, or remote work. Empty means all.                                                             |
| Posted within (days)                 | integer       | No       | Only offers from the last N days. 1 means today. 0 means no limit.                                                             |
| Exclude companies                    | list          | No       | Drop offers from companies whose name contains any of these words.                                                             |
| Only new offers since the last run   | true or false | No       | Return only offers this monitor has not returned before.                                                                       |
| Monitor name                         | text          | No       | A label for the list of seen offers. Use one name per saved search.                                                            |
| Include full description and details | true or false | No       | Adds the full description, posting time, expiry date, and the facts read from the text. Slower. Default off.                   |
| Maximum results                      | integer       | No       | How many offers to save. Default 20, maximum 5,000.                                                                            |
| Parallel requests                    | integer       | No       | How many pages or offers are read at once. Default 3, maximum 6.                                                               |
| Proxy configuration                  | object        | No       | Network settings for the requests. The default works for most runs.                                                            |

### 📊 Data table

| Field                                                                       | Type                | Description                                                                                                                      |
| --------------------------------------------------------------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| id                                                                          | text                | The offer number on Net-Empregos. Stable, so it works as a unique key.                                                           |
| url                                                                         | text                | Direct link to the offer page.                                                                                                   |
| title                                                                       | text                | Job title, with accents kept as written.                                                                                         |
| company                                                                     | text                | Employer name as listed on the offer.                                                                                            |
| companyLogoUrl                                                              | text                | The logo the employer uploaded, when there is one.                                                                               |
| location                                                                    | text                | Town or district printed on the offer card.                                                                                      |
| district, districtId                                                        | text                | The district or region, matched to the site's own list.                                                                          |
| category, categoryId                                                        | text                | Job category as the site labels it, with its ID.                                                                                 |
| jobType, jobTypeId                                                          | text                | Full-time, Part-time, Internship, or Remote work. Present when you filter by job type.                                           |
| workMode, isRemote                                                          | text, true or false | Remote or hybrid, when the title or description says so. Always remote for a remote-only search.                                 |
| datePosted                                                                  | date                | Day the offer was published, YYYY-MM-DD.                                                                                         |
| daysOnline                                                                  | integer             | Days between the posting date and today.                                                                                         |
| isFeatured                                                                  | true or false       | Whether the employer paid to feature the offer.                                                                                  |
| postedAt                                                                    | date and time       | Exact posting time. With details on.                                                                                             |
| validThrough, daysUntilExpiry                                               | date, integer       | Expiry date and days left. With details on.                                                                                      |
| employmentType, industry, region, city                                      | text                | From the offer page. With details on.                                                                                            |
| experienceYearsMin, experienceYearsMax                                      | integer             | Years of experience the ad asks for. 0 when the ad says none is needed. With details on.                                         |
| educationLevels                                                             | list                | Levels the ad mentions: basic_9, secondary_12, professional, bachelor, master, phd. With details on.                             |
| languages                                                                   | list                | Languages the ad names, such as English or French. With details on.                                                              |
| salaryMin, salaryMax, salaryCurrency, salaryPeriod, salaryBasis, salaryText | number, text        | Pay when the ad states an amount: range, EUR, hour, month or year, gross or net, and the sentence it came from. With details on. |
| description                                                                 | text                | Full offer text. With details on.                                                                                                |
| changeType, firstSeenAt                                                     | text, date and time | NEW and when it was first returned. Only in new-offers mode.                                                                     |
| scrapedAt                                                                   | date and time       | When this Actor collected the row.                                                                                               |

Market snapshot rows have their own fields: snapshotDate, dimension (overall, jobType, district, or category), name, openOffers, and, from the second snapshot on, previousOpenOffers, change, and changePercent.

Fields that an offer does not publish are left out of its row. Education, languages, experience, work mode, and salary are read from free text, so they appear only when the ad says so.

Example row with details on:

```json
{
    "id": "16087291",
    "url": "https://www.net-empregos.com/16087291/gestor-a-de-condominios-lisboa/",
    "title": "Gestor/a de Condomínios - Lisboa",
    "company": "O Meu Condomínio",
    "district": "Lisboa",
    "districtId": "1",
    "category": "Administração / Secretariado",
    "categoryId": "29",
    "datePosted": "2026-10-07",
    "daysOnline": 0,
    "isFeatured": true,
    "validThrough": "2026-11-06",
    "daysUntilExpiry": 30,
    "employmentType": "FULL_TIME",
    "experienceYearsMin": 2,
    "educationLevels": ["bachelor"],
    "languages": ["English"],
    "scrapedAt": "2026-10-07T09:12:44.120Z"
}
```

### 💰 Pricing

You pay $1.50 per 1,000 results saved ($0.0015 per result). A run that finds no offers costs nothing. There is no fee to start a run and there are no subscriptions. A market snapshot returns up to 77 rows, so one snapshot costs about $0.12.

### ⭐ Enjoying Net-Empregos Portugal Jobs Scraper: Vagas de Emprego, No Login?

<table width="100%">
<tr>
<td style="padding:20px 24px 14px;background:#E8F5EF;border:1px solid #A9D8C2;border-left:5px solid #0B6E4F;border-radius:10px 10px 0 0">
<span style="font-size:20px;letter-spacing:4px">⭐ ⭐ ⭐ ⭐ ⭐</span><br>
<span style="font-size:17px;font-weight:800;color:#1C1917">Saving hours of manual copying each week is worth a quick rating.</span><br>
<span style="font-size:14px;color:#57534E">A 5-star rating takes 10 seconds and helps other recruiters and analysts find this Actor. Your feedback also shapes the next update.</span>
</td>
</tr>
<tr>
<td style="padding:0;background:#0B6E4F;border:1px solid #A9D8C2;border-top:none;border-radius:0 0 10px 10px;text-align:center">
<a href="https://apify.com/getascraper/net-empregos-jobs-scraper/reviews" style="display:block;padding:13px 16px;color:#FFFFFF;text-decoration:none;font-weight:800;font-size:15px;letter-spacing:0.3px">★&nbsp;&nbsp;Rate this Actor on Apify</a>
</td>
</tr>
</table>

### ❓ FAQ

#### Como extraio vagas de emprego do Net-Empregos?

Enter keywords, pick districts and categories if you want, set the number of offers, and start the run. The results appear in the Output tab, ready to export.

#### How do I get only the new offers every day?

Turn on "Only new offers since the last run", give the search a monitor name, and put the run on an Apify schedule. The first run saves everything that matches, up to your limit, and remembers it. Every later run saves only offers that were not returned before. Use a different monitor name for each saved search. Net-Empregos publishes well over a thousand offers a day, so narrow the search (a district, a category, keywords, or posted within a few days) so that the first run's limit covers it. If the limit cuts the first run short, the log says so, and later runs will report some of the offers it did not reach as new.

#### How do I track how many jobs are open in Portugal?

Choose "Market snapshot" and schedule it daily or weekly. Each run returns the number of open offers for the whole board and for every contract type, district, and category, plus the change since your previous snapshot. Add a keyword to track one skill, for example python.

#### Can I send new offers to Slack, email, or a spreadsheet?

Yes. Apify integrations and webhooks can forward each finished run to Slack, email, Google Sheets, Zapier, Make, or your own endpoint, so a scheduled new-offers run becomes an alert without any code.

#### Does the Actor need a Net-Empregos account?

No. It reads the public search pages and public offer pages. It never asks for a login, password, cookie, or API key.

#### Why do few offers have a salary?

Net-Empregos has no salary field, and most Portuguese ads do not state one. The Actor reads an amount from the ad text only when the text clearly gives pay, and leaves the field out otherwise. In a test of 81 real offers, about 6% stated a salary, 17% a number of years of experience, and 30% an education level.

#### Why are some fields empty for some offers?

Net-Empregos does not publish every detail on every offer. Fields the offer does not show are left out of the row, not filled with placeholders.

#### Why does a run with full details take longer?

Each offer page is opened separately to read its full details. Turn the option off for quick lists, and on when you need the description, expiry date, or the facts read from the text.

#### Is it fast?

A plain list of 20 offers takes about 9 seconds and 200 offers about a minute. The Actor reads several result pages at the same time, but deliberately keeps the number of parallel requests low, because the site blocks clients that send large bursts. Opening every offer for full details is the slow part, because each offer is a separate request.

### 🔗 Other actors

- [CWJobs Scraper: UK Tech Jobs, Salary Bands, and Geo Coordinates](https://apify.com/getascraper/cwjobs-scraper) ↗ - UK tech job listings with salary bands and locations.
- [Aviation Job Search Scraper: Pilot, Crew & Engineer Jobs UK/US](https://apify.com/getascraper/aviation-job-search-scraper) ↗ - Aviation job listings for pilots, crew, and engineers in the UK and US.
- [Ashby Jobs Scraper: Hiring Change Monitor](https://apify.com/getascraper/ashby-jobs-monitor) ↗ - Tracks new and changed job postings on Ashby career pages.
- [CareerCross scraper: キャリアクロス bilingual jobs](https://apify.com/getascraper/career-cross-scraper) ↗ - Bilingual Japanese job listings from CareerCross.

# Changelog

This Actor's version history is a separate document: https://apify.com/getascraper/net-empregos-jobs-scraper/changelog.md

# Actor input Schema

## `mode` (type: `string`):

Job offers returns one row per offer. Market snapshot returns the number of open offers per district, category and job type, with the change since your previous snapshot, which is useful for tracking the Portuguese job market over time.

## `keywords` (type: `string`):

Words the offer must mention, for example a job title or a skill. Leave empty to browse everything that matches the filters below.

## `excludeKeywords` (type: `array`):

Drop offers whose title (or full description, when details are on) contains any of these words. Case and accents are ignored. Example: estágio, comissões.

## `districts` (type: `array`):

Only offers in these places. Includes the Portuguese districts, the islands and the foreign locations the site lists. Leave empty for the whole country. Each choice runs as its own search.

## `categories` (type: `array`):

Only offers in these professional categories. Leave empty for all categories.

## `jobTypes` (type: `array`):

Contract type as listed by the site. Remote work returns the offers the site marks as teletrabalho. Leave empty for all types.

## `postedWithinDays` (type: `integer`):

Only offers published in the last N days, counting today as day 1. Use 1 for today's offers. 0 means no age limit. The run stops reading as soon as results get older than this.

## `excludeCompanies` (type: `array`):

Drop offers from companies whose name contains any of these words, for example recruitment agencies. Case and accents are ignored.

## `onlyNewOffers` (type: `boolean`):

Return only offers this monitor has not returned before, so a daily or hourly schedule gives you a clean feed of new jobs. The first run returns everything that matches, up to the result limit, and records it as the baseline.

## `monitorName` (type: `string`):

A label for the list of offers already seen. Use one name per saved search, so a Lisbon IT feed and a Porto sales feed do not share memory. Changing the name starts a fresh baseline.

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

Open each offer to add the full description, exact posting time, expiry date, industry, and facts read from the text: remote or hybrid, experience, education, languages and salary when stated. Slower, because every offer is one more request.

## `maxItems` (type: `integer`):

Stop after this many offers across all searches. Market snapshot always returns every row, up to 77.

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

How many pages or offers are fetched at the same time. The site slows down clients that send bursts, so keep this low unless you need maximum speed.

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

Apify datacenter proxies work for this site and rotate the exit address on every request, which avoids the site's rate limit.

## Actor input object example

```json
{
  "mode": "jobs",
  "keywords": "",
  "excludeKeywords": [],
  "districts": [],
  "categories": [],
  "jobTypes": [],
  "postedWithinDays": 0,
  "excludeCompanies": [],
  "onlyNewOffers": false,
  "monitorName": "default",
  "includeDetails": false,
  "maxItems": 20,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "mode": "jobs",
    "keywords": "",
    "excludeKeywords": [],
    "districts": [],
    "categories": [],
    "jobTypes": [],
    "postedWithinDays": 0,
    "excludeCompanies": [],
    "onlyNewOffers": false,
    "monitorName": "default",
    "includeDetails": false,
    "maxItems": 20,
    "maxConcurrency": 3,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("getascraper/net-empregos-jobs-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 = {
    "mode": "jobs",
    "keywords": "",
    "excludeKeywords": [],
    "districts": [],
    "categories": [],
    "jobTypes": [],
    "postedWithinDays": 0,
    "excludeCompanies": [],
    "onlyNewOffers": False,
    "monitorName": "default",
    "includeDetails": False,
    "maxItems": 20,
    "maxConcurrency": 3,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("getascraper/net-empregos-jobs-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 '{
  "mode": "jobs",
  "keywords": "",
  "excludeKeywords": [],
  "districts": [],
  "categories": [],
  "jobTypes": [],
  "postedWithinDays": 0,
  "excludeCompanies": [],
  "onlyNewOffers": false,
  "monitorName": "default",
  "includeDetails": false,
  "maxItems": 20,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call getascraper/net-empregos-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,getascraper/net-empregos-jobs-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/rfHY5dSpDPcHnWDs4/builds/jcK0gLIaHQbuubYg4/openapi.json
