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:
-
Python 3.11+ installed on your machine (
apify-client3.x requires it). - The Apify API client library installed (
pip install apify-client). - 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
Store your API token in your shell environment:
export APIFY_API_TOKEN="your_apify_token_here"
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,
}
(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")
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", andmaxItems: 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)
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"
}
Understanding your results
Each dataset row contains structured fields mapped directly from Gupy's search response:
-
id: Unique integer job identifier on Gupy (such as12766238). -
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). -
cityandstate: 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:
- Leverage direct egress: Gupy's API responds without proxy rotation by default.
- Pricing: For current pricing and details, see the Store page.
-
Automate with webhooks: You can register an Apify webhook to receive an HTTP POST when the run finishes. The webhook payload's
resourceprovides the response of the Get Actor run API endpoint (docs.apify.com/platform/integrations/webhooks/actions), which includesdefaultDatasetIdto stream clean records straight into your data warehouse or ATS pipeline. -
Targeted geographic filtering: When researching regional hiring patterns across Brazilian states, specify
state(e.g.,"São Paulo","Minas Gerais") orcity(e.g.,"Curitiba","Belo Horizonte") to narrow results to local corporate branches and technology centers. -
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
workplaceTypeor location filters, Gupy may have zero active vacancies matching all criteria simultaneously. -
Input rejected at startup: The
workplaceTypeandcontractTypeparameters 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 thetypeLabelandtypefields 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)