DEV Community

Cover image for How to Scrape Computrabajo Job Listings with Python
ReventaData
ReventaData

Posted on Originally published at apify.com

How to Scrape Computrabajo Job Listings with Python

By the end of this tutorial, you will have a working Python script that extracts job listings from Computrabajo into structured JSON records: job title, employer, location, salary amounts, working mode, and posting age.

Computrabajo is an employment portal serving job seekers and recruiters across 19 distinct country sites throughout Latin America. Scraping it with ordinary HTTP requests is straightforward because the site returns server-rendered pages without requiring specialized proxy setups. In reach testing conducted on 2026-10-21, direct plain requests with standard browser headers reached the site without requiring a proxy.

In this guide, we use Python and the Apify Actor Computrabajo Scraper (reventadata/computrabajo-scraper). The sample record examined below is a sample from a capture dated 2026-10-21, parsed with the Actor's own parser.

⏱️ Time estimate: About 15 minutes to configure, run, and inspect results.


Prerequisites

To follow this tutorial, you will need:

  1. Python 3.11+ installed locally (apify-client 3.3.0 requires Python 3.11 or newer).
  2. The Apify API client for Python.
  3. An Apify account and API token.

Install the client:

pip install -U "apify-client~=3.0"
Enter fullscreen mode Exit fullscreen mode

The code reads your token from an environment variable:

export APIFY_API_TOKEN="your_apify_token_here"
Enter fullscreen mode Exit fullscreen mode

Find your token on the API & Integrations page in Apify Console.


What you'll achieve

You will turn a Computrabajo search into structured datasets where each row represents one job offer. Each record captures the unique listing id, canonical url, title, employer company, verified employer indicator companyVerified, location, workMode, parsed salaryAmount, raw currency text, and posting date.

Data Boundary Notice: The Actor reads public job-offer pages only. It never accesses candidate profiles, resumes, or curriculum vitae sections, and phone-reveal pages are never requested.

Example use case: Suppose you want to monitor sales openings in the Dominican Republic that print a salary. Configuring country: "do", searchQueries: ["vendedor"], and onlyWithSalary: true returns records where every row includes an explicit salary figure.


Step 1: Access Computrabajo Scraper

Navigate to the Computrabajo Scraper page on Apify Store.

Review the documentation and input parameter tables. In this guide, we drive extraction entirely through Python code.


Step 2: Configure search parameters

The primary parameter is searchQueries: a list of job titles or search terms (such as vendedor or contador). You pair this with country to target one of 19 regional portals (such as do for Dominican Republic, mx for Mexico, or co for Colombia).

Optional parameters let you refine the query:

  • locations: narrows results to specific cities or provinces, such as medellin or bogota-dc.
  • maxPagesPerSearch: limits how many pages each query walks (1 to 499; 20 offers per page).
  • maxItems: sets an absolute ceiling on total rows saved across all searches.
import os
from apify_client import ApifyClient

# 1. Initialize ApifyClient with token from environment
client = ApifyClient(os.environ["APIFY_API_TOKEN"])

# 2. Define the search parameters
run_input = {
    "country": "do",
    "searchQueries": ["vendedor"],
    "maxPagesPerSearch": 1,
    "maxItems": 20,
}
Enter fullscreen mode Exit fullscreen mode

💡 Search syntax note: When a search term contains the Spanish preposition "en" (such as auxiliar en enfermeria), Computrabajo does not combine it with location slugs cleanly. Leave locations empty for such queries and filter by location afterwards.


Step 3: Add optional filters

Computrabajo's robots.txt disallows filtering parameters in URLs (sal=, cont=, pubdate=), so the Actor applies filters client-side after fetching listing cards. Filtered-out rows are dropped before saving and do not count toward your saved items:

Parameter Type Default Description
country string "co" Target portal: one of 19 country codes (ar, bo, cl, co, cr, cu, do, ec, gt, hn, mx, ni, pa, pe, pr, py, sv, uy, ve).
searchQueries array none (prefill ["vendedor"]) Job titles or keywords to search. Give searchQueries, locations or startUrls: the site has no "all offers" listing.
locations array [] Specific city or regional slugs to combine with each query.
maxItems integer 100 Total offers saved across all searches before finishing.
maxPagesPerSearch integer 499 Maximum result pages to walk per query (up to 499 pages).
postedWithinDays integer None Keeps offers posted within N days (0 = today).
workMode string "any" Filters for "remote" or "remote-or-hybrid".
onlyWithSalary boolean false Drops listings that omit an explicit salary amount.
includeKeywords array [] Words the title, company, or location must contain.
excludeKeywords array [] Words that cause an offer to be dropped if present.
includeDetails boolean false Opens individual offer pages for full description, requirements, and skill tags.

Step 4: Run the Actor

Start the extraction using client.actor("reventadata/computrabajo-scraper").call(run_input=run_input). This command triggers the Actor in Apify cloud infrastructure and waits for execution to finish:

# 3. Start the Actor run and wait for it to complete
print("Starting Computrabajo extraction...")
run = client.actor("reventadata/computrabajo-scraper").call(run_input=run_input)
if run is None or run.status != "SUCCEEDED":
    status = run.status if run else "unknown"
    raise SystemExit(f"Run did not succeed (status: {status}).")

# 4. Fetch the saved offers from the dataset
items = client.dataset(run.default_dataset_id).list_items().items
print(f"Retrieved {len(items)} job offers.\n")
Enter fullscreen mode Exit fullscreen mode

Under the hood:

  • The Actor formats the search URL (https://do.computrabajo.com/trabajo-de-vendedor) and fetches pages using standard browser headers.
  • It parses listing cards (20 per page), normalizes salary text, resolves relative posting dates, and drops duplicates across paginated results.
  • It stops when reaching maxItems, the maxPagesPerSearch limit, or the end of available site results.

Step 5: View and download results

Iterate through the returned items to display or process fields in Python:

for item in items:
    title = item.get("title")
    company = item.get("company") or "Confidential"
    location = item.get("location")
    salary = item.get("salaryText") or "Not stated"
    posted = item.get("postedText")
    urgent = " (Urgent)" if item.get("isUrgent") else ""

    print(f"{title}{urgent}")
    print(f"  Company: {company}")
    print(f"  Location: {location}")
    print(f"  Salary: {salary}")
    print(f"  Posted: {posted}")
    print("-" * 40)
Enter fullscreen mode Exit fullscreen mode

Here is one verbatim record, a sample from a capture dated 2026-10-21 (page 1 of the Dominican Republic vendedor search) parsed with the Actor's own parser. A saved row also carries scrapedAt, added at save time:

{
    "id": "3EA3A542A53C85D161373E686DCF3405",
    "url": "https://do.computrabajo.com/ofertas-de-trabajo/oferta-de-trabajo-de-asesora-buscamos-vendedores-comisionistas-en-santo-domingo-de-guzman-3EA3A542A53C85D161373E686DCF3405",
    "country": "do",
    "title": "Asesor/a",
    "company": "Blandino Prebea",
    "companyUrl": "https://do.computrabajo.com/empresas/ofertas-de-trabajo-de-blandino-prebea-40BEFA84642B332D",
    "companyRating": null,
    "companyVerified": true,
    "location": "Santo Domingo de Guzmán, Distrito Nacional",
    "workMode": "remote",
    "isUrgent": false,
    "isFeatured": false,
    "postedText": "Hace 14 horas",
    "postedDaysAgo": 0,
    "postedDate": "2026-10-21",
    "salaryText": "15,000.00 $ (Mensual) + Comisiones",
    "salaryAmount": 15000.0,
    "salaryCurrencySymbol": "$",
    "salaryPeriod": "Mensual",
    "hasCommission": true,
    "searchQuery": "vendedor",
    "searchPlace": null,
    "page": 1
}
Enter fullscreen mode Exit fullscreen mode

Apify datasets can be downloaded in JSON, CSV, XML, Excel, HTML table, RSS, or JSONL formats.


Understanding your results

Each dataset row contains structured properties parsed directly from the listing cards:

  • salaryAmount, salaryCurrencySymbol, salaryPeriod, hasCommission: The numerical value is parsed cleanly from the text while preserving the raw currency symbol ($, US$, Q). The period is extracted from parenthesis (such as Mensual), and commissions are flagged when + Comisiones appears. In the 20-card Dominican Republic capture, 12 listings printed numeric salary figures, 9 included commission incentives, and 8 listings were unpriced.
  • company and companyVerified: Shows employer names and indicates whether Computrabajo has verified the organization. In our capture, 14 of 20 employers were verified. Confidential employers display placeholder text such as Importante empresa del sector while companyUrl remains null.
  • workMode: Distinguishes remote and onsite-or-remote (hybrid) roles. In the capture, 1 offer was marked remote and 3 hybrid.
  • postedDaysAgo and postedDate: Relative age strings (Hace 14 horas, Ayer) are converted into integer days and approximate UTC dates.
  • isUrgent and isFeatured: Flags for paid promotions and urgency badges.

Pro tips

  1. Mind the 499-page ceiling: Computrabajo serves at most 499 result pages for any individual search query (up to 9,980 listings per query). To collect comprehensive regional data, segment large queries by passing individual city names into locations.
  2. Handle Spanish preposition quirks: Search keywords containing the word "en" (such as auxiliar en enfermeria) are read as free text by the site search engine rather than being split cleanly by location. Leave locations blank for these terms and filter titles using includeKeywords.
  3. Selective detail enrichment: Activating includeDetails: true opens each individual offer page with 3 concurrent workers to extract description text, requirement lists, and skill tags. Keep this disabled for fast index sweeps and enable it only when full job text is necessary.
  4. Keyword match enforcement: Computrabajo's search engine matches terms loosely. Use includeKeywords to require that critical words appear in the title, company or location.
  5. Start with small item caps: When building automated pipelines, set maxItems: 20 and maxPagesPerSearch: 1 during initial development to verify field mapping before executing wider searches.

Troubleshooting

  • Run failed with zero rows: Computrabajo Scraper terminates with an error if zero rows are saved. This intentional fail-fast behavior alerts you immediately to mistyped city slugs or overly restrictive keyword filters rather than silently returning empty output.
  • Reading rejection tallies: If fewer items than expected appear in your dataset, examine the log's final summary line: Run finished: N rows pushed, N offer pages failed. Rejections: .... This tally breaks down items dropped by filter reasons: too-old, work-mode, no-salary, or keywords. Read logs programmatically with client.log(run.id).get().
  • Unsupported country codes: Spain (es), Brazil (br), and Portugal (pt) redirect to a gateway portal without job listings and are not supported. Use the 19 validated Latin American codes.
  • Confidential employers: Listings displaying Importante empresa del sector have companyUrl: null because the card carries no employer link.

Pricing and next steps

For current pricing and details, see the Store page.

To automate regular sweeps, save your configured input as an Apify task and assign a schedule using standard cron syntax (0 8 * * * runs every morning at 8 AM). To integrate downstream applications, configure an Apify webhook on the ACTOR.RUN.SUCCEEDED event, which delivers the complete run object containing defaultDatasetId.

Which job markets or roles across Latin America are you looking to monitor on Computrabajo? Share your use case in the comments below!

Top comments (1)

Collapse
 
magia_cc_0f5823d6cb56ed5 profile image
magia c'c •

Keeping postedText beside the approximate UTC date is useful for monitoring jobs across those 19 portals. I would also preserve scrapedAt when applying postedWithinDays: a listing marked yesterday near local midnight can otherwise cross the cutoff between runs. The raw age string makes that boundary easier to audit.