Upwork Scraper
Pricing
$49.99/month + usage
Upwork Scraper
Upwork job scraper that pulls live listings with full filter support for job type, budget, experience level, and duration, so recruiters and developers get structured data without manual searching.
Pricing
$49.99/month + usage
Rating
0.0
(0)
Developer
Kawsar
Actor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Upwork Scraper: Extract Upwork Job Listings with Full Filter Support
Upwork Scraper pulls job listings from Upwork with the same filters you'd set manually: job type, experience level, budget range, duration, and workload. It handles Upwork's JavaScript-heavy pages automatically and returns clean, structured records with job details, required skills, and client data including total spend and hire history.
Use it to monitor new jobs in your niche, research what skills and rates the market is paying, build lead lists, or feed Upwork data into your own tools and dashboards.
Use cases
- Lead generation: spot clients posting jobs in your niche before competitors do
- Market research: track skill demand and budget trends across Upwork categories over time
- Hiring intelligence: monitor what roles are getting posted and at what rate or budget
- Competitive analysis: see how many proposals jobs attract and what experience levels clients want
- CRM enrichment: pull structured job and client data into spreadsheets or your own tooling
- Automated job alerts: run on a schedule and push new matches to Slack, email, or a webhook
Input
| Parameter | Type | Default | Description |
|---|---|---|---|
searchQuery | string | required | Keywords to search on Upwork (e.g. "python developer", "react frontend") |
jobType | string | all | Payment type: all, hourly, or fixed |
experienceLevel | array | [] | One or more of: entry, intermediate, expert. Empty means all. |
sortBy | string | recency | Sort order: recency or relevance |
hourlyRateMin | integer | — | Minimum hourly rate in USD |
hourlyRateMax | integer | — | Maximum hourly rate in USD |
budgetMin | integer | — | Minimum fixed project budget in USD |
budgetMax | integer | — | Maximum fixed project budget in USD |
duration | string | all | Project length: week, month, semester, ongoing, or all |
workload | string | all | Weekly hours: part_time, full_time, or all |
renderJs | boolean | true | Enable JavaScript rendering. Required for Upwork pages. |
maxItems | integer | 10 | Number of job listings to return. Maximum is 10 (one page). |
requestTimeoutSecs | integer | 60 | Per-request timeout in seconds |
timeoutSecs | integer | 300 | Total actor run timeout in seconds |
Example: scrape Python developer jobs (hourly, mid-to-senior level)
{"searchQuery": "python developer","jobType": "hourly","experienceLevel": ["intermediate", "expert"],"sortBy": "recency","hourlyRateMin": 20,"hourlyRateMax": 80}
Example: scrape fixed-price React jobs under $2,000
{"searchQuery": "react frontend developer","jobType": "fixed","experienceLevel": ["entry", "intermediate"],"budgetMin": 100,"budgetMax": 2000,"sortBy": "recency"}
Example: monitor long-term data science contracts
{"searchQuery": "data scientist machine learning","jobType": "hourly","experienceLevel": ["expert"],"duration": "ongoing","workload": "full_time","sortBy": "relevance"}
Example: entry-level writing jobs sorted by recency
{"searchQuery": "content writer blog articles","jobType": "all","experienceLevel": ["entry", "intermediate"],"sortBy": "recency"}
Output
The actor stores results in a dataset. Each job listing produces one record:
{"jobId": "~01234567abcdef89","jobTitle": "Senior Python Developer for Data Pipeline","jobDescription": "Looking for an experienced Python developer to build an ETL pipeline that moves data from Salesforce into BigQuery on a daily schedule...","skills": ["Python", "Apache Airflow", "PostgreSQL", "Google BigQuery", "AWS"],"category": "Web, Mobile & Software Dev","subcategory": "Web Development","jobPaymentType": "hourly","experienceLevel": "Expert","duration": "3 to 6 months","workload": "30+ hrs/week","hourlyRateMin": 30.0,"hourlyRateMax": 60.0,"fixedBudget": null,"budgetText": "$30.00-$60.00/hr","clientCountry": "United States","clientRating": 4.9,"clientJobsPosted": 47,"clientTotalSpent": 24500.0,"clientTotalHires": 12,"clientPaymentVerified": true,"proposalCount": "10 to 15","connectsRequired": 6,"publishedAt": "2025-03-15T10:22:00.000+00:00","postedAgo": "2 hours ago","jobUrl": "https://www.upwork.com/jobs/~01234567abcdef89","scrapedAt": "2025-03-20T08:45:12.123456+00:00"}
Output fields reference
| Field | Type | Description |
|---|---|---|
jobId | string | Upwork job identifier |
jobTitle | string | Job posting title |
jobDescription | string | Job description text |
skills | array | Required skill tags |
category | string | Upwork job category |
subcategory | string | Upwork job subcategory |
jobPaymentType | string | hourly or fixed |
experienceLevel | string | Entry, Intermediate, or Expert |
duration | string | Expected project duration |
workload | string | Weekly hours commitment (e.g. "30+ hrs/week") |
hourlyRateMin | number | Min hourly rate in USD |
hourlyRateMax | number | Max hourly rate in USD |
fixedBudget | number | Fixed budget in USD |
budgetText | string | Formatted budget or rate (e.g. "$30.00-$60.00/hr") |
clientCountry | string | Client country |
clientRating | number | Client feedback score (0-5) |
clientJobsPosted | integer | Total jobs this client has posted |
clientTotalSpent | number | Total USD spent by this client on Upwork |
clientTotalHires | integer | Total freelancers hired by this client |
clientPaymentVerified | boolean | Whether the client's payment method is verified |
proposalCount | string | Proposal count range (e.g. "10 to 15") |
connectsRequired | integer | Connects needed to apply |
publishedAt | string | ISO 8601 timestamp the job was posted |
postedAgo | string | Relative time since posting (e.g. "2 hours ago") |
jobUrl | string | Direct URL to the job on Upwork |
scrapedAt | string | ISO 8601 timestamp when the record was scraped |
How it works
- Builds a search URL from your query and active filters
- Fetches the page using a rendering engine with residential proxy support
- Parses job tiles directly from the rendered HTML
- Transforms each job into a clean record and pushes it to the dataset
- Returns up to 10 results from the first page of search results
What data does this actor extract?
For each job listing, the actor extracts the job title, full description, skill tags, category, subcategory, payment type, rate or budget, experience level, project duration, and workload. It also captures client-side data: country, feedback rating, payment verification status, total jobs posted, total amount spent on Upwork, total hires, proposal count, Connects required to apply, and a relative posted time (e.g. "2 hours ago").
FAQ
What if some fields come back null? Upwork's page structure changes over time. A null field means it was not present on that listing or the parser did not find it in the current layout. The record is still saved with all fields that were successfully extracted.
How many results can I get per run?
Up to 10 per run — one page of Upwork search results. Use maxItems if you need fewer.
Can I filter by multiple experience levels at once?
Yes. Pass an array to experienceLevel, for example ["intermediate", "expert"], and both filters are applied to the search.
Can I run this on a schedule? Yes. Use Apify's built-in scheduler with a cron expression. Pair it with a webhook to push new results to Slack, Google Sheets, or your CRM automatically after each run.
What happens if the page fails to load? The actor logs the HTTP status code and stops cleanly. Any results already collected are saved to the dataset.
Integrations
Connect Upwork Scraper with other apps and services using Apify integrations. You can integrate with Make, Zapier, Slack, Airbyte, GitHub, Google Sheets, Google Drive, and many more. You can also use webhooks to trigger actions whenever new job results are available.