Guru Scraper [$0.90/1K💰] | Jobs | Budget | Client Spend
Pricing
from $0.88 / 1,000 results
Guru Scraper [$0.90/1K💰] | Jobs | Budget | Client Spend
Scrape Guru.com freelance jobs by keyword and export title, budget, skills, client history, quote count, posting age and a direct link as clean JSON. Uses Guru's own JSON API, no browser. Built for freelance lead-gen and market research.
Pricing
from $0.88 / 1,000 results
Rating
0.0
(0)
Developer
Ahmed Jasarevic
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Guru Scraper — Freelance Jobs & Budgets API
Scrape freelance jobs from Guru.com into a clean dataset. Give it a keyword (or any Guru job-listing URL) and it returns one record per job with the budget, skills, posting age, quote count, client history and a direct link. It runs on plain HTTP — no browser, no headless Chrome — against Guru's own JSON search API first and the server-rendered listing pages as a fallback, which keeps runs fast and cheap at $0.90 / 1,000 results.
Main use cases
- Freelance lead generation — collect fresh Guru jobs that match your skills and pitch them before the quote count climbs.
- Freelance job monitoring — schedule recurring searches and get new postings with budgets and client history as they appear.
- Market and rate research — track budgets, hourly rates and durations across categories to price your own services.
- Freelance jobs database / marketplace intelligence — build a spreadsheet or warehouse of Guru postings to analyse demand by skill, category and client country.
- Client prospecting — filter by
employerTotalSpentandemployerCountryto find clients who already spend on the platform.
How it works
The actor searches Guru for each keyword you provide (or opens any Guru listing URL) and writes one record per job. It tries Guru's internal JSON search API first — one request carries 20 jobs, with the full, un-truncated title, description, budget, skills and client history — and falls back to the server-rendered listing pages if the API is unavailable. It is a CheerioCrawler (HTTP-only, 256 MB, concurrency 3); nothing in the pipeline renders a page.
Every record carries source: "api" or source: "html" so a dataset always says which surface produced it.
Extract Freelance Jobs From Guru.com For Lead Generation
| Field | Example |
|---|---|
title | FullStack Developer for Platform Rebuild |
url | https://www.guru.com/jobs/fullstack-developer-for-platform-rebuild/2119273 |
jobId | 2119273 |
budgetType | Hourly / Fixed Price |
budgetAmount | $25 - $40, $1k-$2.5k, No Rate specified |
budgetText | Hourly | $25 - $40 | 30+ hrs/wk | 3-6 months |
hoursPerWeek | 30+ hrs/wk |
duration | 3-6 months |
postedDate / postedDateIso | Jul 06, 2026 / 2026-07-06 |
deadline | Aug 05, 2026 (the "Send before" date) |
quotesCount | 117 |
skills | ["JavaScript", "Node.js", "ReactJS", …] |
category / subcategory | Programming & Development / Web Development & Design |
employerName | Eddie M |
employerCountry | United States |
employerTotalSpent | 1400 (lifetime spend on Guru, null when not shown) |
description | The full job post text |
titleFromDetail | true when the title is the one Guru stores, not the listing's ~40-char truncation |
source | api (Guru's JSON search API) or html (listing page) |
keyword / sourceUrl | Which search produced this job |
Build A Freelance Jobs Database Without The Guru API
Guru has no public API, so the actor uses the same internal surface Guru's own web app calls.
- Bootstrap. One request to
https://www.guru.com/api/jobs/1/detailsstatisticssummaryanswers302withSet-Cookie: _accessToken=…— an anonymous JWT Guru issues to every visitor. No login, no OAuth handshake, no page to render. - Search. Each keyword becomes
GET https://www.guru.com/api/search/job/?query=<base64-of-the-listing-path>withAuthorization: Bearer <token>: 20 jobs per page, the stored title (no listing truncation), full descriptions, budget, skills and client history in one payload — a single request replaces a listing page plus one detail page per job. The cookie alone is not enough (401 without the bearer header), andquerymust be the base64 of the listing path. - Fallback. If the API answers
401/403or anything unexpected (Imperva has flagged Apify's datacenter ranges), the run queues the original server-rendered listing pages and continues there — that path needs the residential proxy. Server-rendered pages carry the full data in plain HTML (pageData.TotalResultsplus theul#ctl00_guB_ulpaginatepager drive pagination; each job is a<div class="record jobRecord" data-gid="…">), so a CheerioCrawler parses it directly.
Anti-bot (Imperva / Incapsula). Three request properties decide whether guru.com answers with content or a challenge, and the actor pins all three — each was measured side-by-side through the same proxy IP, URL and headers, changing only one property at a time:
| Property | Wrong value → | Correct value (shipped) |
|---|---|---|
| Protocol | HTTP/2 → 212-byte challenge | HTTP/1.1 (http2: false) |
| TLS ClientHello | got-scraping's Chrome-cipher tlsHook → challenge | stock OpenSSL (https.minVersion: 'TLSv1.2') |
| User-Agent | Chrome UA on Node TLS → HTTP 403 challenge | curl/8.5.0 |
Imperva grades UA ↔ TLS consistency: a Chrome UA on a Node/OpenSSL ClientHello gets a 403, while a plain curl/8.5.0 UA on the identical request returns the full page. No paid anti-bot service and no browser are required.
Other reverse-engineering notes.
- Keyword URL spelling. Guru maps a free-text keyword onto a
/skill/{slug}/path segment using the transform it ships in its own bundle (spaces →-, literal hyphens →--, then URL-encode), e.g.web design→https://www.guru.com/d/jobs/skill/web-design/. The legacy/d/jobs/q/{slug}/form answers404. - Block-page detection. Real Guru pages also embed an Imperva monitoring script, so matching
_Incapsula_Resourceflags every valid page. The genuine block page is an ~800-byte document containingIncapsula incident ID, so the detector requires that banner (or a tiny body). - IP reputation matters for the HTML path. The same listing request that fails from Apify's datacenter ranges passes from a residential proxy IP; the API is tried first and only falls back to HTML.
- Failure handling. Challenge pages and
>= 400responses are detected, logged with a snippet of what Guru actually served, and the session is retired so the retry runs on a fresh session/proxy — instead of being silently written to the dataset.
Input Parameters
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
keywords | array of strings | No (prefilled) | ["web design", "python"] | Search terms. Each becomes https://www.guru.com/d/jobs/skill/{keyword}/. |
startUrls | array (requestListSources) | No | https://www.guru.com/d/jobs/ | Direct listing URLs (category, skill, budget or saved-search pages). When set, these override keywords. |
maxResults | integer | No | 60 | Maximum jobs to collect in total (max 2000). |
maxPagesPerKeyword | integer | No | 5 | Pagination depth per search. 20 jobs/API page, 10 jobs/HTML page. |
fetchFullTitles | boolean | No | true | In HTML fallback mode opens each job's page for the full title/description (+1 request per job). The JSON API always returns full titles. |
maxRequestsPerCrawl | integer | No | 120 | Hard cap on HTTP requests; auto-raised if smaller than maxResults needs. |
proxy | object (proxy) | No | useApifyProxy: false | Standard Apify proxy picker — use the residential group for the HTML path. |
Free accounts get a 10-job preview per run; paid accounts run up to maxResults.
Output Fields
One dataset item per job (24 fields). The default overview view shows Job title, Budget type, Budget, Quotes, Posted, Client and Job URL.
| Field | Type | Description |
|---|---|---|
jobId | string | Guru project id (data-gid; also the last path segment of the job URL). |
title | string | Job title, complete as Guru provides it. |
url | string | Direct link to the job. |
budgetType | string / null | Hourly or Fixed Price. |
budgetAmount | string / null | Rate or fixed price as displayed, e.g. $25 - $40. |
budgetText | string / null | Complete budget line as shown in the listing. |
hoursPerWeek | string / null | Weekly commitment for hourly jobs. |
duration | string / null | Expected project duration. |
postedDate | string / null | Posted date as Guru displays it. |
postedDateIso | string / null | Posted date normalized to YYYY-MM-DD. |
deadline | string / null | The "Send before" date. |
quotesCount | number / null | Number of quotes the job has received. |
description | string / null | Full job description text. |
skills | array of strings | Skills attached to the job. |
category | string / null | Top-level Guru category. |
subcategory | string / null | Guru subcategory. |
employerName | string / null | Client who posted the job. |
employerCountry | string / null | Client country. |
employerTotalSpent | number / null | Lifetime spend on Guru (null when not displayed). |
titleFromDetail | boolean | True when the title is Guru's stored title, not the ~40-char truncation. |
source | string / null | api or html. |
keyword | string / null | Search keyword this job was found under (null for explicit URLs). |
sourceUrl | string | Listing/search URL this job was parsed from. |
scrapedAt | string | ISO timestamp of when the job was parsed. |
Example Input And Output
Input
{"keywords": ["web design", "python"],"maxResults": 60,"maxPagesPerKeyword": 5,"proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }}
Output (one dataset row)
{"jobId": "2119273","title": "FullStack Developer for Platform Rebuild","url": "https://www.guru.com/jobs/fullstack-developer-for-platform-rebuild/2119273","budgetType": "Hourly","budgetAmount": "$25 - $40","budgetText": "Hourly | $25 - $40 | 30+ hrs/wk | 3-6 months","hoursPerWeek": "30+ hrs/wk","duration": "3-6 months","postedDate": "Jul 06, 2026","postedDateIso": "2026-07-06","deadline": "Aug 05, 2026","quotesCount": 117,"description": "We are rebuilding our SaaS platform and need a full-stack developer...","skills": ["JavaScript", "Node.js", "ReactJS"],"category": "Programming & Development","subcategory": "Web Development & Design","employerName": "Eddie M","employerCountry": "United States","employerTotalSpent": 1400,"titleFromDetail": true,"source": "api","keyword": "web design","sourceUrl": "https://www.guru.com/d/jobs/skill/web-design/","scrapedAt": "2026-07-06T09:12:03.000Z"}
Integrations & Automation
Every Apify actor is reachable through the Apify API, and this one plugs into webhooks, Zapier and Make so new jobs can be routed to Slack, a Google Sheet, Notion, Airtable or a CRM. For lead generation, run it on a schedule — a daily search for your skills is enough to catch fresh postings early, and recurring runs also improve the actor's Store recommendation signals. You can also run it from the Apify Console or via the API with POST https://api.apify.com/v2/acts/ahmed_jasarevic~guru-scraper/runs.
Related Actors
- upwork-job-scraper — the largest Upwork jobs scraper; pairs Guru and Upwork coverage for freelance lead-gen.
- upwork-scraper — broader Upwork marketplace data (jobs and profiles).
- careerjet-scraper — job listings from a major global job aggregator.
- myworkdayjobs-scraper — corporate job postings from Workday career sites.
- superprof-scraper — tutor/freelance marketplace listings to widen the freelance dataset.
FAQ
Is there an official Guru.com API?
Guru does not offer a public API. This actor uses Guru's own internal JSON search API with the anonymous access token Guru issues to every visitor, so you get structured jobs without an API key or an account.
What are the alternatives to this actor / this data source?
For freelance-market data you can combine this with Upwork and Fiverr scrapers. Guru is a distinct, long-running freelance marketplace, so its postings, budgets and client spend complement the other platforms rather than duplicate them.
How do I get new freelance web-design or Python jobs?
Set keywords to the skills you care about (e.g. ["web design", "python"]), choose maxResults, and schedule the actor daily. Each run returns the latest matching jobs with budget, skills, quote count and a direct link.
What does employerTotalSpent mean?
It is the amount the client has spent on Guru over their lifetime, as shown on the listing. It is null when Guru does not display it — it is a useful signal for filtering out low-value clients.
Do I need a proxy?
The JSON search API has answered from datacenter IPs, so many runs need no proxy. The HTML fallback path sits behind Imperva and requires the residential proxy group. The actor tries the API first and only needs the proxy when it falls back.
How is this cheaper than other Guru scrapers?
It returns 20 jobs per request with the full title and description, so a single API call replaces a listing page plus one detail page per job. At $0.90 / 1,000 results it is the lowest per-result Guru price observed in the Store.
SEO Keywords
guru, guru.com, guru scraper, guru jobs, guru freelance, guru api, freelance jobs api, freelance lead generation, freelance job monitoring, upwork scraper, fiverr scraper, freelance marketplace data, job budget tracking, client spend data, python jobs, web design jobs
For AI Agents & LLM Apps
Purpose: return one structured freelance-job row per Guru.com job for a given keyword or listing URL.
Minimal working input:
{ "keywords": ["web design"], "maxResults": 60 }
Variant (URL-driven, overrides keywords):
{ "startUrls": [{ "url": "https://www.guru.com/d/jobs/c/programming-development/" }], "maxResults": 60 }
Output fields: jobId, title, url, budgetType, budgetAmount, budgetText, hoursPerWeek, duration, postedDate, postedDateIso, deadline, quotesCount, description, skills, category, subcategory, employerName, employerCountry, employerTotalSpent, titleFromDetail, source, keyword, sourceUrl, scrapedAt.
Behaviors an agent should know:
startUrlsoverrideskeywordswhen both are set.- If
maxResultsis left unset it defaults to 60; free-plan runs are capped at 10 jobs. sourceisapiorhtml; the JSON API path is tried first and needs no proxy, the HTML fallback needs a residential proxy.fetchFullTitles: true(default) only adds requests in HTML fallback mode; the JSON API always returns full titles.keywordisnullwhen the job came from an explicitstartUrlsentry.employerTotalSpentmay benullwhen Guru does not display it.
Billing: pay-per-event — $0.0009 per result ($0.90 / 1,000 results) plus a $0.00005 actor-start event.
Legal & Compliance Disclaimer
This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Guru. It accesses only publicly available Guru.com pages and the anonymous access token Guru issues to every visitor; it does not log in, bypass authentication, or solve CAPTCHAs on anyone's behalf. Users are responsible for ensuring their use complies with Guru's Terms of Service and robots.txt, and with applicable data-protection law. Output may include client names and countries; where personal contact data is present it must not be used for unsolicited commercial outreach in violation of applicable law (e.g. CAN-SPAM, GDPR).