Dice Jobs Scraper (US tech jobs)
Pricing
from $0.60 / 1,000 jobs
Dice Jobs Scraper (US tech jobs)
Scrape Dice, the US tech job board, by posted date: above the site's 10,000-row limit a search is split automatically and what stays out of reach is counted. Each job with its full job page (description, skills, contract, apply link). Pay per job.
Pricing
from $0.60 / 1,000 jobs
Rating
0.0
(0)
Developer
Hexagone Data
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
21 hours ago
Last modified
Categories
Security
Limited permissionsShare
Scrape Dice, the US tech job board. Type a search term or paste the URL your browser shows, filters included, and get one record per job: title, company, location, salary, employment and employer type, remote and Easy Apply flags, and the job page details (full description, skills, contract type and term, postal code, how to apply).
What it does, measured on the site on 2026-11-06:
- Above the site's 10,000-row limit: split automatically, and what stays out of reach is counted. The search page shows at most 25 pages of 30 jobs
(750); the site's search service stops at 10,000 rows per search. Above 10,000, the Actor splits the search by the site's own filters (employer type, Easy
Apply, visa sponsorship, work from home, remote, then US state) and puts it back together, each job delivered once. What no split can reach is counted in the
run summary (status
partial_collection, numbermissing), never hidden. Measured on 2026-11-06:java12,251 of 12,251 jobs (done);python29,993 of 30,233 (partial_collection, 240 missing, counted). Measured dry onpython: 30,235 jobs announced, 58 slices, none above 10,000; jobs with no state (location "US" only, or none) cannot be reached by the state slices: 473 of the 19,006 jobs of the deepest slice. The Actor also reads that slice itself, newest first, up to 10,000 rows. The whole site (113,369 jobs): about 97% reachable, estimated from a dry split: California alone holds 11,290 jobs in a slice no filter can split further, and about 2,900 jobs (2.6%) are out of reach; a run on it ends inpartial_collectionwith the numbers. - By posted date, nothing lost between pages. The site's default order (relevance) lets jobs with the same score swap places from one read to the next:
reading
kubernetesin Texas page after page, 100 jobs at a time, gave 2,196 then 2,197 distinct jobs out of 2,198. The Actor always reads by posted date, 1,000 rows at a time: 2,198 of 2,198. - The same search as the site's page. For each search, the Actor opens the search page once and sends the site's search service the exact parameters that page sends (location, coordinates, radius, every filter), so any URL the site understands is read the way the site reads it.
- The job page is included, at the same price. Full description (text and HTML), every skill (the page folds them behind "Show more"), contract type (W2, corp-to-corp, independent) and term, postal code, Position Id, and the apply link or e-mail the page serves. On 51 job pages read: skills 50, apply link 32, apply e-mail 19, postal code 39, contract type 14.
- Salary as numbers only when the text is unambiguous.
salaryMin,salaryMax,salaryCurrencyandsalaryPeriodare filled only when the salary text states both the currency and the period ("USD 197,300.00 - 225,100.00 per year", "$45 - $55 hourly"): 1,307 of 3,332 rows measured (39%). Otherwise they arenull, and the salary text is always delivered as the site wrote it ("Depends on Experience", "120000 - 150000"). - The run tells you what it got. Distinct jobs against the total announced at the start and read again at the end, with both numbers if anything is missing.
Try it with 20 jobs
- Keep the prefilled search term (
python developer) and Maximum number of jobs = 20. - Click Start. You pay for 20 jobs: $0.022 (job pages included, start fee included).
- Open Jobs overview for the table, Run summary for what was collected and why anything is missing.
What to paste
Type words in Search terms and use the filters of the form (location, radius, posted within, employment types, workplace types, employer types, Easy Apply only, willing to sponsor only), or paste into Start URLs:
| You paste | Example | What you get |
|---|---|---|
| A search | https://www.dice.com/jobs?q=python&location=Austin%2C+TX%2C+USA | the search read to the end (above 10,000 jobs: split, what is out of reach counted) |
| A search with filters | https://www.dice.com/jobs?q=python&filters.employmentType=CONTRACTS&filters.workplaceTypes=Remote&radius=50 | the same filters as the site |
| The URL copied after clicking a job on the list | https://www.dice.com/jobs?q=python&location=Austin%2C+TX%2C+USA&latitude=30.267153&longitude=-97.7430608&countryCode=US&locationPrecision=City&adminDistrictCode=TX&selectedJobId=8863ad7f-... | the search it shows, not only that job |
| The site's other search pages | https://www.dice.com/jobs/q-python-jobs, /jobs/l-texas-jobs, /jobs/q-python-l-austin%2c+tx-jobs, https://www.dice.com/jobs/l-mclean%2c+va%2c+us-jobs?filters.clientBrandNameFilter=Capital+One | read as the site reads them |
| The site itself | https://www.dice.com/jobs exactly, with Maximum number of jobs = 0 | about 97% of the 113,369 jobs measured on 2026-11-06, the rest counted (partial_collection) |
A single job (https://www.dice.com/job-detail/..., or an old https://www.dice.com/jobs/detail/...) | not supported yet: the URL is rejected with this reason; paste a search URL |
page and pageSize in a URL are replaced (the search is read 1,000 rows at a time) and named in the run summary (droppedParams), like any other
parameter the site's own page does not use (selectedJobId, utm_source...): they have no effect. A filter of the form that the site's page does not send
to its search is reported (OPTION_WITHOUT_EFFECT), never silently dropped. Any other address (another site, the home page, a company page, any other
path under /jobs/) is rejected with the reason; the other addresses of the run are still read. The site answers unknown paths under /jobs/ with a
search of the whole site, so a URL that asks for a search (words, a place, a filter, a /jobs/... path) but whose page sends an empty search to the site is
rejected after that page ("this URL would read the whole site").
A location the site does not understand filters nothing, and the Actor checks it. The site keeps any location text, even one it does not use.
Measured on 2026-11-06: Anywhere, Work from home or a typo gave 113,044 jobs (the whole site); Remote, USA gave 10,914, a real filter (the same
as filters.workplaceTypes=Remote). So for each search with a location, the Actor makes
two control counts, one after the other: the search as the site's page sends it, then the same search without the location (one row each, before any
job is delivered, never charged). The site's totals move by a few jobs from one request to the next (six identical counts of the whole site varied by 10;
the page and the search API differed by up to 35 out of 112,863), so the two counts are taken as the same when they differ by at most 3 jobs or 0.2% of
the larger one: the location filtered nothing. Then a URL with no words and no filter is rejected ("this URL would read the whole site: Dice did not
use the location ..."); with words or a filter, the search is read and the run summary warns (LOCATION_NO_EFFECT), giving both counts. If a control
count fails, the search is still read, with a warning (LOCATION_NOT_CHECKED). On the searches we measured, a real location removed thousands of jobs (Texas: 21,159 against 112,851). Limits: a
location the site reads as another place is a real filter for the check and nothing is said (Remote US gave 110,376 jobs, as many as United States,
2.4% less than the whole site: the site reads it as the US, not as remote jobs); a small search whose jobs all lie in the location you gave, or where it
removes 3 jobs or fewer, also gets the same two counts: the warning can then be wrong, but a search with words or a filter is never rejected for it.
A search with a location also includes remote jobs, as on the site: the site's page sends includeRemote=true with any location (measured:
data engineer + Phoenix, 441 remote jobs out of 467). "Remote" is not a place on Dice: as a
location it filters nothing (q=python 30,157 jobs, q=python&location=Remote 30,157, q=python&filters.workplaceTypes=Remote 3,080). For remote jobs,
use Workplace types = Remote (filters.workplaceTypes=Remote); "Remote" or "remote only" typed in the form's Location, and "Remote US", "Remote USA",
"Remote - US" or "Remote (US)" (read by the site as the US), are turned into Workplace types = Remote (the workplace types you chose are kept), and the
run summary says so (LOCATION_REMOTE_AS_WORKPLACE); if Remote is already among them, the location is sent as typed and checked like any other. In a
pasted URL, the location is read as the site reads it. An empty form is refused.
Output
One record per job and run (jobId is the key: a job found by two of your searches is delivered once). Unknown values are null, never "", 0 or false: an empty
or blank text served by the site is delivered as null. One exception: isFeatured is false when the site does not mark the job (the site leaves the field
out for jobs it does not feature).
Every field is listed in the dataset schema. A real record, built from the site's own data captured on 2026-11-06, abridged (texts and skills shortened):
{"jobId": "02b3cfd1-af9d-42f0-be19-0165a0c93840","legacyJobId": "08beeaf16ba51f3df617bec0d2d1cbda","url": "https://www.dice.com/job-detail/02b3cfd1-af9d-42f0-be19-0165a0c93840","title": "Line Support Technician Plant Floor Desktop Support (3rd Shift)","companyName": "Calance","companyProfileId": "736fcdd4-39f2-5eef-b3fd-23f427d39cfd","companyProfileUrl": "https://www.dice.com/company-profile/736fcdd4-39f2-5eef-b3fd-23f427d39cfd","diceId": "cxbcsi","location": "Anna, Ohio, USA","city": "Anna","state": "Ohio","stateCode": "OH","country": "USA","postedDate": "2026-11-06T01:01:44Z","salary": "USD 45,302.00 per year","salaryMin": 45302,"salaryMax": 45302,"salaryCurrency": "USD","salaryPeriod": "year","employmentType": "Contract","employmentTypes": ["Contract"],"employerType": "Direct Hire","workplaceTypes": ["On-Site", "Hybrid"],"isRemote": false,"workFromHome": true,"easyApply": false,"willingToSponsor": false,"isFeatured": false,"externalApplyUrl": null,"summary": "CALL US NOW for immediate consideration! ** We will NOT accept 3rd Party (C2C) Contractor ...","detailsStatus": "ok","description": "CALL US NOW for immediate consideration!\n===\n** We will NOT accept 3rd Party (C2C) Contractors **\n...","skills": ["Remote Support", "Project Management", "Preventive Maintenance", "Performance Management", "Network Support", "React.js"],"postalCode": "43040","validThrough": "2026-12-07T01:01:44.000Z","positionId": "Job45206","applyType": "APPLY_TO_URL","applyUrl": "https://www.calancejobs.com/bcsijobs.nsf/o/45206?OpenDocument&s=DiceAd","applyEmail": null,"contractTypes": ["CONTRACT_W2"],"contractTerm": "6 Months","searchUrl": "https://www.dice.com/jobs?q=contract","scrapedAt": "2026-11-06T08:31:57Z"}
detailsStatus: ok; expired (the job was removed between the list and its page: list data delivered, page fields null); not_found; failed (the
job page could not be read after 3 tries, the job stays delivered from the list); skipped (job pages stopped for this run after repeated refusals);
null when Include the job page details is off. The job page is always read at https://www.dice.com/job-detail/<jobId>, even when the card links to
a /direct-apply/ page (about 5% of jobs), which leaves Dice.
Run summary
Each run writes a readable Run summary (and the same as JSON in OUTPUT), per search: status, jobs, jobsDistinct (distinct jobs seen for this
search; when the run stopped at your maxItems or maximum charge: distinct jobs delivered for it), totalAnnounced, totalAtEnd (read again after
the last page), missing (null when the run stopped at your maxItems or maximum charge: jobs not read are not lost), totalOnSearchPage, slices, slicesOver10000, slicesReread,
slicesStillMoving, passes, droppedParams, orderNote (the order of the records, see Known limits), detail. For the run: rejectedUrls,
detailsRead, detailsFailed, detailsExpired, detailsNotFound, detailsStopped, accessRefusals, serverErrors, accessLevel, anomalies.
| Status | Meaning |
|---|---|
done | every distinct job counted against the total read at the end; at most 2 jobs or 0.1% missing, shown with its number (warning MISSING_WITHIN_TOLERANCE) |
partial_collection | something is missing: both numbers and the cause; warning PARTIAL_COLLECTION |
stopped_at_limit | your maxItems or maximum charge was reached: jobsDistinct = jobs delivered, totalAnnounced kept, missing null |
no_results | the site announced 0 jobs: the search is empty, the URL is wrong or the site is down (NO_RESULTS warning) |
no_new_jobs | the jobs of this search were all delivered by an earlier search |
blocked_by_site, rate_limited, network_error, http_error, not_found, site_maintenance | the site refused or did not answer even after new sessions: never reported as an empty search |
unrecognized_page, structure_changed | the answer is not a search the Actor can read; never reported as an empty search |
not_processed, interrupted, internal_error | the search was not reached or finished (limit reached before it, run stopped, unexpected error) |
If jobs are missing after the last page, the first page of each slice is read again, and the slices that still lack jobs are read to the end; at most 3
readings per slice in all, passes included. Only what was missing is added, nothing is delivered or charged twice. A job delivered without its job page is
counted in detailsFailed or detailsStopped and in the warning DETAILS_FAILED. A run where no search delivers anything fails with the exact cause.
Warnings are listed under Checks; "Checks passed" is shown only when there is none. Codes starting with ANO_ come from the shared run checks.
Pricing
Pay per event: $0.85 per 1,000 jobs, the job page included: the same price with or without Include the job page details. Plus a $0.005 start fee per run (charged by Apify once per GB of memory; the default is 1 GB). Apify subscribers pay less automatically, on every event: 10% off on the Bronze plan, 20% on Silver, 30% on Gold and above.
| Jobs | With job pages, start fee included | Without job pages, start fee included |
|---|---|---|
| 20 | $0.022 | $0.022 |
| 1,000 | $0.855 | $0.855 |
Only jobs written to your dataset are paid, each once, even if two of your searches find it or the list is read twice. Your maximum charge per run is respected: the run stops cleanly before the job that would exceed it, and no job page is read for a job that could not be paid.
Known limits
- Order: newest first within each search (and within each slice when a search is split above 10,000); jobs the site features come first on the first
page. There is no order across slices or searches. With a small
maxItems(10,000 or less) a search is not split: you get its most recently posted jobs, after the 0 to 3 jobs the site features (they can be older). AsortByin your URL is ignored (orderNotesays so), because the site's own order loses jobs between pages. - A single job URL is not accepted yet (
/job-detail/...): paste a search URL. - "Remote" is not a location on Dice, nor is any text the site does not understand ("Anywhere", "Work from home", a typo: 113,044 jobs, the
whole site). Each location is checked with two counts, with and without it: if they differ by at most 3 jobs or 0.2% (the site's totals move by a few
jobs between requests), the URL is rejected if it has no words and no filter, read with a warning (
LOCATION_NO_EFFECT) otherwise. "Remote US" is read by the site as the United States (110,376 jobs, likeUnited States): in a pasted URL it is a real filter for the check, so nothing is said; typed in the form's Location, it is turned into Workplace types = Remote. A small search whose jobs are all in that location (or where it removes 3 jobs or fewer) gets the same counts too: the warning may then be wrong. Remote jobs are asked with Workplace types = Remote (filters.workplaceTypes=Remote: 3,080 forpython, against 30,157 with or withoutlocation=Remote). - A location also brings remote jobs, as on the site (
includeRemote=trueis sent by the site's page):data engineer+Phoenixgave 441 remote jobs out of 467. - Expired jobs still listed by the site. In our 11 test searches read to the end with job pages, 0% to 1% of the jobs the search shows had a job page answering "no longer
available" (HTTP 410), some posted months ago: they are delivered from the list and charged like the others, with
detailsStatus: "expired". - Platform migrations (Apify moving the run to another server) are resumed from the saved state; jobs found in your dataset are not written again. If one hits while a batch of jobs is being written, the resumed run reads the dataset back for 3 minutes: jobs already there are kept, and only the jobs still missing after that are written, once. If the Apify storage itself fails and the run has to stop, the run ends with "PARTIAL RESULT", says how many jobs you received, and tells you to resurrect the run (run page > Actions > Resurrect) to get the rest without paying again for the jobs already delivered; a new run with the same input starts from zero.
- No number of applicants: the site does not show it without an account.
- No e-mails searched outside Dice:
applyEmailis only the apply e-mail the job page itself serves. - No incremental mode: each run reads what you ask, from the newest down, and has no memory of earlier runs.
- Jobs out of reach in very large searches. Above 10,000 jobs, the last split is by US state; jobs listed with no state are read only among the newest
10,000 of their slice (
python: 240 missing of 30,233). A slice still above 10,000 with no filter left gives its newest 10,000 rows (on the whole site: California, 11,290). Any job still missing is counted in the run summary (partial_collectionwith the numbers), never reported asdone. - New jobs keep coming during a long run: a few may be missing at the end (counted). A job whose page could not be read is still delivered and charged:
its list data is complete,
detailsStatustells which. After 10 refused job pages in a row, the run pauses and tries one; after 3 refused tries, job pages stop for the run (detailsStopped). - No proxy is used by default: no refusal was measured from a direct connection, Apify's datacenter proxy or Apify's residential proxy (3 tries each). If the
site refuses (HTTP 403 or 429, or a challenge page instead of the answer), the run retries with new sessions, then falls back to Apify's datacenter proxy
(US), then, for the search list only (1,000 jobs per request), to Apify's residential proxy (US). Job pages never go through the residential proxy: if they
are refused through the datacenter proxy too, job pages stop for the run (
detailsStopped, warningDETAILS_STOPPED) and the list goes on. A server error of the site (HTTP 500, 502, 503, 504) is not a refusal: it is retried after a pause and counted (serverErrors); a page still failing is counted as failed; it never changes the proxy. Your price per job is the same whatever the proxy. This fallback has been tested offline only. The search service needs the key that the site's own page serves: the Actor reads it from the page at the start of the run and again if it is refused; if the page no longer serves it, the run stops with that reason.
Support
Questions, a URL that does not work, a field you need: open an issue on the Actor's Issues tab with the run link.
This Actor is not affiliated with, endorsed or sponsored by Dice or DHI Group, Inc. The name is used only to describe the website the data comes from. Only publicly visible job ads are collected; ad texts and apply e-mails can contain personal data such as a recruiter's name: use the data in line with the site's terms and the privacy laws that apply to you.