DEV Community

Cover image for How to Scrape Gupy Job Openings in Brazil with Python
ReventaData
ReventaData

Posted on Originally published at apify.com

How to Scrape Gupy Job Openings in Brazil with Python

By the end of this tutorial, you will have a working Python script that extracts live Brazilian job openings from Gupy into structured JSON: job titles, hiring employers, workplace arrangements (remote, hybrid, on-site), contract types (such as CLT and legal entity roles), application deadlines, PcD accessibility indicators, and complete vacancy descriptions.

Gupy is a recruitment platform widely used by Brazilian enterprises across banking, technology, retail, and manufacturing. Scraping job boards manually is repetitive and slow.

In this guide, we use Python and the Apify Actor Gupy Jobs Brazil Scraper (reventadata/gupy-jobs-scraper). In our live benchmark run (configured with searchQueries: ["python"], workplaceType: "remote", and maxItems: 10), the Actor took 4.2 seconds to extract 10 job openings into a structured dataset using direct API egress.

⏱️ Time estimate: About 30 minutes.


Prerequisites

To follow this tutorial, you will need:

  1. Python 3.11+ installed on your machine (apify-client 3.x requires it).
  2. The Apify API client library installed (pip install apify-client).
  3. An Apify account with an API token.

Sign up for a free Apify account. Copy your personal API token from API & Integrations in Apify Console. Install the client:

pip install apify-client
Enter fullscreen mode Exit fullscreen mode

Store your API token in your shell environment:

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

What you'll achieve

By completing this tutorial, you will extract structured vacancy records directly from Gupy's career portal into clean JSON: role identifiers, hiring company names, corporate career portal logos, contract classifications, workplace models, municipal locations, deadlines, and role descriptions.

Note on Data Boundaries: This Actor collects public corporate job postings from Gupy's recruitment search endpoint. It gathers no applicant personal information, resumes, candidate identifiers, or Brazilian national registration numbers (CPF), keeping extraction strictly compliant with public recruitment intelligence standards.

Example use case: Suppose your recruitment intelligence team needs to audit active remote engineering roles in Brazil. Setting searchQueries: ["python"] and workplaceType: "remote" returns clean records with hiring requirements, tech stacks, and company branding.


Step 1: Access Gupy Jobs Brazil Scraper

Navigate to the Gupy Jobs Brazil Scraper page on Apify Store.

The Store page's "Try for free" button opens Apify Console. In this guide, we drive the Actor programmatically via Python.


Step 2: Configure search parameters

In your Python script, import the client and prepare your extraction parameters in run_input:

import os
from apify_client import ApifyClient

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

# 2. Define the extraction parameters
run_input = {
    "searchQueries": ["python"],
    "workplaceType": "remote",
    "maxItems": 10,
}
Enter fullscreen mode Exit fullscreen mode

(Note: This demonstration snippet uses maxItems: 10 for a fast initial test. The benchmark run cited in this guide ran with searchQueries: ["python"], workplaceType: "remote", and maxItems: 10.)


Step 3: Configure optional settings and filters

Gupy Jobs Brazil Scraper supports several optional parameters to tailor your search results:

Parameter Type Default Description
searchQueries array Required List of role titles, skills, or job keywords (e.g., ["python"]).
workplaceType string "all" Work model filter: all, remote, hybrid, or on-site.
contractType string "all" Employment type: all, vacancy_type_effective (CLT), vacancy_type_internship, vacancy_type_apprentice, or vacancy_type_temporary.
state string None Optional Brazilian state name (e.g., "São Paulo").
city string None Optional Brazilian city name (e.g., "Curitiba").
maxItems integer 50 Maximum job records to collect before stopping (minimum 1).
proxyConfiguration object Direct Proxy settings (useApifyProxy: false by default, as Gupy public API supports direct egress).

Input values for workplaceType and contractType are enforced by the Actor's schema; an unlisted option is refused before the run starts.


Step 4: Run the Actor

Trigger execution with client.actor("reventadata/gupy-jobs-scraper").call(run_input=run_input):

# 3. Start the Actor run and wait for it to complete
print("Starting Gupy Jobs Brazil extraction...")
run = client.actor("reventadata/gupy-jobs-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 resulting dataset items
dataset = client.dataset(run.default_dataset_id).list_items().items

print(f"Extraction complete! Retrieved {len(dataset)} job openings.\n")
Enter fullscreen mode Exit fullscreen mode

Behind the scenes:

  • The Actor queries Gupy's public recruitment search API using direct egress without requiring residential proxies.
  • It paginates through search results in batches of up to 50 (PAGE_LIMIT = 50) and transforms raw job JSON into normalized schema fields.
  • In our live benchmark run, configured with searchQueries: ["python"], workplaceType: "remote", and maxItems: 10, the Actor collected 10 job openings in 4.2 seconds.

Step 5: View and download results

Once execution finishes, iterate over dataset to inspect and format each job posting:

for item in dataset:
    job_id = item.get("id")
    title = item.get("name")
    company = item.get("companyName")
    workplace = item.get("workplaceType")
    contract = item.get("typeLabel")
    pcd = item.get("disabilities")
    url = item.get("jobUrl")

    pcd_flag = " [PcD]" if pcd else ""
    print(f"Job #{job_id}: {title}{pcd_flag}")
    print(f"  Company: {company}")
    print(f"  Model: {workplace} | Contract: {contract}")
    print(f"  Apply: {url}")
    print("-" * 50)
Enter fullscreen mode Exit fullscreen mode

Here is a verbatim sample record extracted during our benchmark run:

{
  "id": 12766238,
  "name": "Desenvolvedor Backend Sênior - NodeJS/Java/Python",
  "companyName": "Deliver IT",
  "careerPageName": "Deliver IT",
  "careerPageLogo": "https://attachments.gupy.io/production/companies/562/career/644/images/logo.png",
  "type": "vacancy_type_effective",
  "typeLabel": "Efetivo (CLT)",
  "workplaceType": "remote",
  "city": "",
  "state": "",
  "publishedDate": "2026-10-22T10:59:10.263Z",
  "applicationDeadline": "2026-12-30T00:00:00.000Z",
  "disabilities": true,
  "jobUrl": "https://deliverit.gupy.io/job/eyJqb2JJZCI6MTI3NjYyMzgsInNvdXJjZSI6Imd1cHlfcG9ydGFsIn0=?jobBoardSource=gupy_portal",
  "description": "Você se considera uma pessoa que tem sede por aprendizado, gosta de trabalhar em equipe e curte compartilhar conhecimento? Então essa oportunidade é para você! \nEstamos em busca de um(a) Desenvolvedor Backend Sênior com Sólida experiência em NodeJS, Java e Python, para atuar em um cliente global de comércio eletrônico. Presente em 45 países, publicando anúncios classificados na Internet.\n\nResponsabilidades e atribuiçõesNa sua rotina de trabalho, você vai se deparar com as seguintes atividades: Atuar em um time multidisciplinar;Realizar discovery para entender as regras de negócios e pensar em soluções escaláveis;Atuar com desenvolvimento de soluções ponta a ponta;Desenvolver soluções e resolver as questões na causa raiz das necessidades da companhia;Acompanhar os canais de alerta, identificar impasses, à fim de mitigá-los e propor soluçõesDefinir e desenvolver arquitetura para novas features, mantendo rastreabilidade e observabilidade de todo o desenvolvimento.Requisitos e qualificaçõesConfere abaixo o que você vai precisar saber pra se dar bem nessa oportunidade!CONHECIMENTOS EXIGIDOS Experiência com o desenvolvimento de software, de preferência em arquitetura de microsserviços;Conhecimento em arquitetura de software e boas práticas de desenvolvimento;Sólida experiência com NodeJS, Java e Python;Vivência com sistemas em produção e cloud platform;Conhecer Terraform;Conhecer Mensageria, principalmente Kafka;Capacidade de elaborar testes unitários e de integração;Experiência com metodologias ágeis e práticas ágeis (Ex: TDD, Pair Programming, CI, CD);Conhecimentos em AWS;Experiência com Banco de dados Relacionais e Não Relacionais;Experiência com Docker e Kubernetes;Conhecimento sobre observabilidade.CONHECIMENTOS DESEJÁVEIS  Ter participado de grandes iniciativas ou projetos com alta complexidade/ambiguidade;Atuação em projetos que envolvem milhões de usuários;Conhecer GraphQL;Experiência com NestJS.Informações adicionaisA Deliver IT vai deixar a digital nesse projeto e quer convidar você para fazer parte dessa construção! 🙆‍♀️Temos uma cultura leve, descontraída, colaborativa e diversa, além de um ambiente enriquecedor, com muitos colegas feras em diversos segmentos e muitos desafios. Aqui você vai encontrar projetos inovadores, conexão e muita troca de conhecimento! 😊⭐Fomos eleitos pela GPTW a 5° Melhor empresa para se trabalhar no RS. 🤩 Todas as nossas posições seguem o modelo de contrato CLT em 44h/semanais.CONFIRA NOSSOS BENEFÍCIOSModalidade: 100% RemotoVA e/ou VRPrograma Bem-Estar: apoio psicológico, apoio jurídico, apoio social, apoio financeiro e ginástica laboral. Plano de Saúde e Plano OdontológicoSeguro de VidaAuxílio CrecheParcerias que te dão desconto: Sucesu, Target Trust, Sesc e SeprorgsPremiação por aniversário de empresaPremiação por indicação contratada",
  "searchQuery": "python",
  "scrapedAt": "2026-10-23T17:33:53.780084+00:00"
}
Enter fullscreen mode Exit fullscreen mode

Understanding your results

Each dataset row contains structured fields mapped directly from Gupy's search response:

  • id: Unique integer job identifier on Gupy (such as 12766238).
  • name: Official job title published by the employer.
  • companyName: Name of the hiring company (e.g., Deliver IT, Stefanini Group, Grupo Boticário).
  • careerPageName: Portal brand name hosting the opening.
  • careerPageLogo: URL pointing to the employer's hosted logo image.
  • type: Machine contract identifier code (vacancy_type_effective, vacancy_legal_entity, vacancy_type_talent_pool).
  • typeLabel: Localized human-readable contract label (Efetivo (CLT), Vacancy Legal Entity, Banco de Talentos).
  • workplaceType: Workplace arrangement (remote, hybrid, on-site).
  • city and state: Municipality and state names in Brazil (empty string for broad remote roles).
  • publishedDate: ISO 8601 publication timestamp.
  • applicationDeadline: ISO 8601 application closing deadline.
  • disabilities: Boolean flag indicating inclusion for Persons with Disabilities (PcD).
  • jobUrl: Direct application link for candidate submissions.
  • description: Complete corporate text covering responsibilities, mandatory qualifications, and benefits.

Our benchmark run extracted 10 remote openings across 9 distinct employers. Across the 10 vacancies, 6 were Efetivo (CLT), 3 were Vacancy Legal Entity, and 1 was Banco de Talentos. In addition, 8 positions were flagged for Persons with Disabilities and 2 were not flagged.


Pro tips and advanced usage

To optimize your recruitment data pipelines, consider the following operational practices:

  1. Leverage direct egress: Gupy's API responds without proxy rotation by default.
  2. Pricing: For current pricing and details, see the Store page.
  3. Automate with webhooks: You can register an Apify webhook to receive an HTTP POST when the run finishes. The webhook payload's resource provides the response of the Get Actor run API endpoint (docs.apify.com/platform/integrations/webhooks/actions), which includes defaultDatasetId to stream clean records straight into your data warehouse or ATS pipeline.
  4. Targeted geographic filtering: When researching regional hiring patterns across Brazilian states, specify state (e.g., "São Paulo", "Minas Gerais") or city (e.g., "Curitiba", "Belo Horizonte") to narrow results to local corporate branches and technology centers.
  5. Combine role keywords: You can pass multiple job titles in searchQueries (such as ["python", "analista de dados"]) in a single run to collect vacancies across diverse technical domains.

Troubleshooting common issues

Here are solutions for common situations encountered when querying Gupy:

  • Run fails with zero rows: the Actor ends with 'Zero jobs pushed to dataset'. Verify your search terms. If you provide a very narrow query combined with strict workplaceType or location filters, Gupy may have zero active vacancies matching all criteria simultaneously.
  • Input rejected at startup: The workplaceType and contractType parameters accept specific enumerated values. If an unsupported value is supplied, the platform refuses the request before the run starts.
  • Unexpected contract labels: Gupy allows employers to define legal entity roles (vacancy_legal_entity) or talent pools (vacancy_type_talent_pool). Check the typeLabel and type fields to filter contracts appropriately.
  • Consulting logs: If an extraction ends unexpectedly, open the run log in Apify Console to inspect HTTP status codes. Additional troubleshooting guides are available in the platform documentation at docs.apify.com.

Next steps

Now that you have a functioning Python integration, you can schedule regular extraction jobs on Apify Console to track Brazilian hiring volume, or feed structured vacancies into your private recruitment database.

Explore further integrations in the Apify documentation and review API parameters on the Store page.

What Brazilian tech stacks or hiring trends are you planning to track with Gupy data?

Top comments (0)