Dataspryva

Use Bayt.com MENA Job Listing & Salary Scraper with Python

Search Bayt.com job listings across Middle East and North Africa countries by keyword, location, career level, and employment type. Get titles, companies, locations, salaries, required skills, full descriptions, and apply links.

1. Choose the data you need

Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.

2. Prepare a source-based input

This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.

{
  "careerLevel": "any",
  "companyUrls": [],
  "country": "uae",
  "datePosted": "any",
  "easyApplyOnly": false,
  "employmentType": "any",
  "includeCompanyJobs": false,
  "includeDetails": false,
  "industry": "any",
  "jobIds": [],
  "maxItems": 2,
  "maxPages": 1,
  "mode": "search",
  "remoteOnly": false,
  "searchQueries": [
    "accountant"
  ],
  "sortBy": "date",
  "startUrls": []
}

Download input.example.json and save your reviewed copy as input.json.

FieldTypeRequiredDescription
modestringoptionalWhat to scrape. Search jobs builds one Bayt search per query. Paste URLs accepts job, search or company links. Job IDs resolves specific postings. Company pulls a profile and its open roles.
searchQueriesarrayoptionalOne keyword per entry, for example accountant or software engineer. Several entries are searched in order and duplicates are removed.
countrystringoptionalBayt market to search. Pick International for every country, or choose one of the 24 supported markets.
citystringoptionalOptional city name such as Dubai, Riyadh or Cairo. If Bayt has no page for the city, the search falls back to the whole country.
employmentTypestringoptionalFilter by the employment type Bayt publishes for the job.
careerLevelstringoptionalFilter by seniority. Bayt publishes this for some jobs, mostly employer postings.
datePostedstringoptionalOnly return jobs Bayt marks as posted within this window.
sortBystringoptionalNewest first is best for monitoring. Most relevant is best for broad keyword research.
industrystringoptionalFilter by one of Bayt's employer industries.
companyNamestringoptionalOptional employer name filter, for example Al Futtaim or Infosys. Bayt matches the employer facet, so partial names may work differently from exact names.
remoteOnlybooleanoptionalUse Bayt's server-side remote-working filter.
easyApplyOnlybooleanoptionalOnly return jobs that accept an application directly on Bayt.
minSalaryintegeroptionalExclude jobs whose published USD monthly range ends below this amount. Jobs with no published salary are excluded when this is set.
includeDetailsbooleanoptionalOn: full descriptions, skills, preferred-candidate criteria, parsed salary and company metadata. Off: faster, listing-card fields only.
maxItemsintegeroptionalOverall record limit for the run. Bayt exposes at most about 10,000 results per single search.
maxPagesintegeroptionalSafety cap on listing pages per search. Bayt shows 30 jobs per page and stops near 10,000 results.
startUrlsarrayoptionalJob, search or company URLs, used when Mode is Paste URLs. Arabic and English Bayt URLs are accepted.
jobIdsarrayoptionalBayt job IDs such as 5498312, or full job URLs, used when Mode is Resolve job IDs.
companyUrlsarrayoptionalBayt company profile URLs or numeric company IDs, used when Mode is Company profile.
includeCompanyJobsbooleanoptionalIn Company mode, also return the company's open roles as job records.

3. Start an Actor run

Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.

Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.

import json
import os
import urllib.request

# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
    actor_input = json.load(stream)

token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
    "https://api.apify.com/v2/acts/Q4xXkQSUwkQkVnB7E/runs?timeout=120&maxTotalChargeUsd=0.50",
    data=json.dumps(actor_input).encode("utf-8"),
    headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
    method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
    run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.

4. Inspect the actual results

Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.

Bayt.com job records with salary, location, company, requirements and provenance, plus company profiles when Company mode is used.

Questions before you run

Which inputs are required?

No top-level fields are marked required in the published schema. Conditional requirements can still apply; check the README.

What does this guide verify?

The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.

What if the run request times out?

Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.

Generated from source build dmkWw6R5TxYj7Fdkk and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.