# InfoJobs Jobs Scraper (`parsebird/infojobs-jobs-scraper`) Actor

Scrape job listings from InfoJobs.net: titles, descriptions, salaries, contract types, teleworking status, companies, and posting dates.

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

## Pricing

from $0.80 / 1,000 jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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

### InfoJobs Jobs Scraper

Extract job offers from [InfoJobs.net](https://www.infojobs.net/), Spain's largest job board, with a single search URL.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Turn any InfoJobs keyword, location, or date-range search into structured job data — titles, full descriptions, salaries, contract type, and teleworking status across 26 output fields.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
parsebird/infojobs-jobs-scraper on Apify. Call: ApifyClient("TOKEN").actor("parsebird/infojobs-jobs-scraper").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items for results. Key inputs: searchUrl (string, an InfoJobs search URL, e.g. "https://www.infojobs.net/jobsearch/search-results/list.xhtml?keyword=java&sortBy=PUBLICATION_DATE&sinceDate=_24_HOURS", default is the unfiltered InfoJobs listing page), results_wanted (integer, max unique job offers to save, default 20), max_pages (integer, max search-results pages to process, default 5), proxyConfiguration (object, optional Apify Proxy settings, default {"useApifyProxy": false}). Output fields per job: id, title, description_text, description_html, city, offer_url, application_origin, contract_type, workday, teleworking, published_at, company_name, company_url, salary_min, salary_max, salary_period, salary_currency, salary_type, states, upsellings, executive, newbo_id, search_page, sort_by, since_date, only_foreign_country. Full actor spec: fetch via GET https://api.apify.com/v2/acts/parsebird~infojobs-jobs-scraper (Bearer TOKEN). Get token: https://console.apify.com/account/integrations
```

### What does InfoJobs Jobs Scraper do?

**InfoJobs Jobs Scraper** collects structured job offer data from [InfoJobs.net](https://www.infojobs.net/), Spain's largest job board, using any InfoJobs search URL as input. It reads every filter already encoded in the URL — keyword, location, sort order, publication date, foreign-country toggle — and returns clean, ready-to-use job data without any browser automation.

Use it as an **InfoJobs API alternative** to pull Spanish job market data into JSON, CSV, or Excel. No coding required — paste a search URL, set how many offers you want, and click Start. Or call it through the [Apify API](https://docs.apify.com/api/v2) to automate recurring job data collection.

- 🔍 **Any InfoJobs search** — keyword, category, province, contract type, remote work, salary range — anything encoded in the search URL is respected
- 📄 **Full job descriptions** — both plain text and HTML-formatted versions, fetched from each offer's detail page
- 💶 **Structured salary data** — minimum, maximum, period, currency, and gross/net type, parsed out of InfoJobs' own salary ranges
- 🏠 **Remote work status** — on-site, hybrid, or fully remote (`teleworking`), plus contract type and workday/schedule
- 🏢 **Company details** — employer name and InfoJobs company profile URL
- 📅 **Recency filters** — pass `sinceDate` in the search URL to pull only jobs posted in the last 24 hours, week, or month
- 🔄 **Scheduling and monitoring** — run daily or weekly with [Apify scheduling](https://docs.apify.com/platform/schedules) to track new postings
- 🔗 **API access and integrations** — connect to Google Sheets, Zapier, Make, webhooks, or any workflow via the Apify API

### What data can you extract from InfoJobs?

| Field | Description |
|-------|-------------|
| `id` | Unique InfoJobs offer identifier |
| `title` | Job title |
| `description_text` | Full job description as plain text |
| `description_html` | Job description with basic HTML formatting |
| `city` | City or location of the offer |
| `offer_url` | Absolute URL of the InfoJobs offer |
| `contract_type` | Contract type (e.g. Indefinido, Temporal) |
| `workday` | Work schedule (e.g. Completa, Parcial) |
| `teleworking` | Remote, hybrid, on-site, or other modality |
| `published_at` | Publication timestamp |
| `company_name` | Employer name |
| `company_url` | Employer profile URL on InfoJobs |
| `salary_min` / `salary_max` | Salary range, when published |
| `salary_period` / `salary_type` | Anual/Mensual and Bruto/Neto |
| `states` | Offer status tags (e.g. NEW, REUSED) |
| `executive` | Whether the offer is marked as an executive role |

### How to scrape InfoJobs

1. Go to [InfoJobs.net](https://www.infojobs.net/ofertas-trabajo) and build a search with the filters you want (keyword, location, sort order, date range)
2. Copy the resulting URL from your browser's address bar
3. Open the [InfoJobs Jobs Scraper](https://apify.com/parsebird/infojobs-jobs-scraper) page on Apify Store and click **Try for free**
4. Paste the URL into the **Search URL** field
5. Set **Results wanted** and **Max pages** to control run size and cost
6. Optionally enable **Apify Proxy** for larger or recurring runs
7. Click **Start** and wait for the run to finish
8. Download your data in **JSON, CSV, Excel**, or connect via the **Apify API**

#### Python API example

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("parsebird/infojobs-jobs-scraper").call(run_input={
    "searchUrl": "https://www.infojobs.net/jobsearch/search-results/list.xhtml?keyword=java&sortBy=PUBLICATION_DATE&sinceDate=_24_HOURS",
    "results_wanted": 50,
    "max_pages": 10,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['title']} — {item['company_name']} — {item.get('city')}")
```

#### JavaScript API example

```javascript
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("parsebird/infojobs-jobs-scraper").call({
    searchUrl: "https://www.infojobs.net/jobsearch/search-results/list.xhtml?keyword=java&sortBy=PUBLICATION_DATE&sinceDate=_24_HOURS",
    results_wanted: 50,
    max_pages: 10,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.log(`${item.title} — ${item.company_name} — ${item.city ?? "N/A"}`);
});
```

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `searchUrl` | string | No | `https://www.infojobs.net/jobsearch/search-results/list.xhtml` | InfoJobs search URL whose supported query parameters define the search |
| `results_wanted` | integer | No | `20` | Maximum number of unique job offers to save. Minimum value is 1 |
| `max_pages` | integer | No | `5` | Maximum number of search-results pages to process. Minimum value is 1 |
| `proxyConfiguration` | object | No | `{ "useApifyProxy": false }` | Optional Apify Proxy settings for request reliability |

### Output example

```json
{
  "id": "6acc847e4b435aa2e4daed9ab3f673",
  "title": "Senior Software Developer C++",
  "description_text": "MISION DEL PUESTO\nRealizara de manera cualificada las funciones del puesto.",
  "description_html": "<p><strong>MISION DEL PUESTO</strong><br>Realizara de manera cualificada las funciones del puesto.</p>",
  "city": "Madrid",
  "offer_url": "https://www.infojobs.net/madrid/senior-software-developer-c/of-i6acc847e4b435aa2e4daed9ab3f673",
  "application_origin": "search-new",
  "contract_type": "Indefinido",
  "workday": "Completa",
  "teleworking": "Híbrido",
  "published_at": "2026-07-30T10:22:10Z",
  "company_name": "Example Company",
  "company_url": "https://www.infojobs.net/example-company/em-i123456789",
  "salary_min": 45000,
  "salary_max": 60000,
  "salary_period": "Anual",
  "salary_currency": "EUR",
  "salary_type": "Bruto",
  "states": ["ACTIVE"],
  "upsellings": [],
  "executive": false,
  "newbo_id": "987654321",
  "search_page": 1,
  "sort_by": "PUBLICATION_DATE",
  "since_date": "_24_HOURS",
  "only_foreign_country": false
}
```

Download results in JSON, HTML, CSV, or Excel.

### Use cases

- 📊 **Job market analysis** — track salary ranges, contract types, and remote-work adoption across roles and cities in Spain
- 🧭 **Recruitment sourcing** — monitor new postings for specific keywords or categories as they go live
- 🏢 **Competitor hiring intelligence** — watch which companies are hiring, for which roles, and at what pace
- 📈 **Salary benchmarking** — collect published salary ranges by role, contract type, or location
- 🔄 **Recurring monitoring** — schedule daily or weekly runs with `sinceDate` filters to catch only new offers
- 🔗 **Data pipeline integration** — feed job data into a warehouse, spreadsheet, or BI dashboard via the Apify API

### How it works

1. Parses the `searchUrl` you provide, preserving every InfoJobs query parameter (keyword, sort, date range, foreign-country toggle)
2. Requests each search-results page (`page=1`, `page=2`, …) up to `max_pages`, reading the job offer list embedded in the page
3. Stops pagination early once `results_wanted` unique offers are collected or a page returns no offers
4. Fetches each offer's own detail page to pull the full HTML/plain-text description, contract type, workday, and teleworking status
5. Normalizes salary data into minimum, maximum, period, currency, and gross/net type
6. Pushes each job offer to the Apify dataset, deduplicated by offer ID

### How much does it cost to scrape InfoJobs?

| Event | Price per event | Price per 1,000 |
|-------|----------------|-----------------|
| `job-offer-scraped` (Free plan) | $0.0009 | **$0.90** |
| `job-offer-scraped` (Bronze/Silver/Gold plans) | $0.0008 | **$0.80** |

One event is charged each time a job offer is successfully scraped and saved to the dataset — you only pay for offers actually returned. Apify offers a **free trial** with platform credits, enough to scrape thousands of job offers at no cost.

### FAQ

**Do I need to build a search URL myself?**
Yes — search on [InfoJobs.net](https://www.infojobs.net/ofertas-trabajo), apply the filters you want, and copy the resulting URL into the `searchUrl` input. Any InfoJobs query parameter the site accepts (keyword, sortBy, sinceDate, onlyForeignCountry, category, province, and more) is passed through unchanged.

**How fresh is the data?**
Data is fetched fresh on every run directly from InfoJobs. Use `sinceDate=_24_HOURS` (or `_7_DAYS`, etc.) in your search URL to limit results to recently posted jobs.

**Why do I need `max_pages` and `results_wanted`?**
`max_pages` caps how many search-results pages are requested; `results_wanted` caps how many unique offers are saved. The run stops as soon as either limit is hit, so you control cost and runtime precisely.

**Does this scraper fetch full job descriptions?**
Yes. Each offer's own detail page is fetched to retrieve the complete description (both plain text and HTML), not just the summary shown on the search-results page.

**Do I need Apify Proxy?**
Not for typical runs. `proxyConfiguration` is optional and can help reliability on larger or more frequent runs.

**Can I schedule recurring runs?**
Yes. Use [Apify scheduling](https://docs.apify.com/platform/schedules) to run daily or weekly, combined with a `sinceDate` filter in your search URL to collect only new postings each time.

**Can I access the data via API?**
Yes. Every run produces a dataset accessible via the [Apify API](https://docs.apify.com/api/v2), usable from Python, JavaScript, Google Sheets, Zapier, Make, or any HTTP-capable tool.

### Is it legal to scrape InfoJobs?

This Actor extracts publicly available data from InfoJobs.net. Scraping public data is generally considered legal based on recent court rulings, including the US Ninth Circuit's decision in *hiQ Labs v. LinkedIn*. However, users are responsible for ensuring their use of scraped data complies with applicable laws, InfoJobs' Terms of Service, and data protection regulations including GDPR. Do not use extracted personal data for unsolicited contact or purposes incompatible with the original collection context. For more information, read Apify's blog post on [web scraping legality](https://blog.apify.com/is-web-scraping-legal/).

### Other job scrapers on Apify

Browse all ParseBird actors, including other job board scrapers, on the [Apify Store](https://apify.com/parsebird).

# Actor input Schema

## `searchUrl` (type: `string`):

InfoJobs search URL whose query parameters (keyword, sortBy, sinceDate, onlyForeignCountry, etc.) define the search.

## `results_wanted` (type: `integer`):

Maximum number of unique job offers to save.

## `max_pages` (type: `integer`):

Maximum number of search-results pages to process.

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

Optional Apify Proxy settings for request reliability. Recommended for larger runs.

## Actor input object example

```json
{
  "searchUrl": "https://www.infojobs.net/jobsearch/search-results/list.xhtml",
  "results_wanted": 20,
  "max_pages": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "searchUrl": "https://www.infojobs.net/jobsearch/search-results/list.xhtml",
    "results_wanted": 20,
    "max_pages": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/infojobs-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 = {
    "searchUrl": "https://www.infojobs.net/jobsearch/search-results/list.xhtml",
    "results_wanted": 20,
    "max_pages": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/infojobs-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 '{
  "searchUrl": "https://www.infojobs.net/jobsearch/search-results/list.xhtml",
  "results_wanted": 20,
  "max_pages": 5
}' |
apify call parsebird/infojobs-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/infojobs-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/IVp9Ucoo3MHCfp9pt/builds/tfXEPprQiYO7rnirF/openapi.json
