PracticeMatch Physician & Healthcare Jobs Scraper avatar

PracticeMatch Physician & Healthcare Jobs Scraper

Pricing

from $2.00 / 1,000 jobs

Go to Apify Store
PracticeMatch Physician & Healthcare Jobs Scraper

PracticeMatch Physician & Healthcare Jobs Scraper

Scrape all 40,900+ physician, advanced-practitioner and healthcare jobs on PracticeMatch. Real salary ranges on about half the board, O*NET specialty codes and mappable coordinates. HTTP-only, no browser, no proxy.

Pricing

from $2.00 / 1,000 jobs

Rating

0.0

(0)

Developer

Piquno

Piquno

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 days ago

Last modified

Share

Every one of the 40,900+ physician, advanced-practitioner and healthcare jobs on PracticeMatch.com — with the salary range, which 10 of the 12 most recent postings published.

Most job boards withhold pay. Physician recruiting does not. On a live run of the newest 12 postings, 10 carried a real pay range — for example an Orthopedic Surgeon at $650,000–$750,000/year, Obstetrics & Gynecology at $439,296–$486,245/year, and a Hospitalist at $173–$213/hour. That is the point of this actor. Every posting also carries its O*NET SOC code, so specialties join cleanly to BLS wage data instead of needing string matching.

HTTP-only. No browser, no proxy, no login.


What you get

One flat row per posting — no nested objects or arrays, so CSV and Excel exports are clean.

FieldWhat it is
jobId, jobUrl, professionStable id, canonical URL, and which of the three boards it came from
title, description, descriptionHtmlPosted title and the full posting, as text and as original HTML
employerName, employerUrlHiring organisation and its own website
specialty, socCode, specialtySlug"Family Medicine Physicians", 29-1215.00, and the URL slug
salaryMin, salaryMax, salaryPeriod, salaryCurrency, salaryDisclosedThe published range and whether there is one at all
streetAddress, locationCity, locationState, locationPostalCode, locationCountryFull address
latitude, longitudeCoordinates where the posting carries them
employmentType, directApplyFULL_TIME / PART_TIME / etc, and whether it is a direct-apply listing
datePosted, datePostedRaw, validThroughNormalised to UTC, plus the site's original string
scrapedAt, fieldsPopulatedWhen the row was taken, and how many of its fields are non-null

Measured fill rates

Measured on two live 12-posting runs on 2026-08-23 — counted, not estimated. Salary disclosure depends heavily on how recent a posting is, so both ends are given:

FieldFill
jobId, jobUrl, title, description100%
employerName, employerUrl, specialty, specialtySlug100%
locationCity, locationState, locationCountry, datePosted100%
socCode92%
locationPostalCode, employmentType83%
streetAddress, latitude, longitude58%
salaryMin, newest postings (the default)83%
salaryMin, oldest postings on the board42%
salaryMax33–75% — some postings publish a floor with no ceiling
validThrough0% — the site does not publish expiry dates

Nothing is ever invented to fill a gap: a field the site did not publish stays null. A salary published as a bare minimum keeps salaryMax null rather than copying the floor into it.


Coverage

The sitemap is the only complete index, and it is split across three shards. All figures below were counted, not estimated:

BoardPostingsURL shape
Physicians32,528/physicians/job-details.cfm/{id}/...
Advanced practitioners8,376/advanced-practitioners/job-details.cfm/{id}/...
Healthcare546/healthcare/jobs/job-details/{id}
Total40,903 distinct job ids

The site's paged browse pages cannot reach all of this, which is why seeding is done from the sitemap.


Input

{
"professions": ["physician"],
"specialtyContains": "Family Medicine",
"locationState": "Texas",
"withSalaryOnly": true,
"maxJobs": 500
}

Defaults: maxJobs is 12 and requestDelaySecs is 5 — a quick sample that finishes in about 90 seconds. Raise maxJobs for a real extract and budget the time (see below).

locationState takes either TX or Texas. startUrls accepts PracticeMatch job-details URLs directly and overrides the board selection. newestFirst is on by default and walks the board from the most recently created postings backwards.

Speed, and the trade-off you should understand

Read this before your first big run. PracticeMatch publishes Crawl-Delay: 5 in its robots.txt, and this actor honours it by default. Each job is one request, so:

requestDelaySecsThroughput1,000 jobs takes
5 (default, what the site asks for)~720 jobs/hour~1h 25m
lowerfasteryour call, and your blocking risk

requestDelaySecs is adjustable. Lowering it departs from what the site asks for, and that is your decision rather than the default. A full 40,900-job extract at the default delay is a multi-day run — most buyers want a specialty or a state, not the whole board.

Monitoring the board

Set incremental: true with its own stateKey. Only postings not seen before are emitted, tagged changeType: "new", so a daily watch bills for the handful that are actually new rather than re-billing everything.


Filters are applied before billing

titleContains, specialtyContains, locationState, employmentType, withSalaryOnly and postedWithinDays all run before a row is charged. You are never billed for a row a filter excluded.


Limitations — read before you buy

  • Salary disclosure tracks recency. 10 of the newest 12 postings published a range; only 5 of the oldest 12 did. With the default newestFirst you are on the good end of that, but disclosure is never universal — use withSalaryOnly when you need it.
  • The board carries stale postings, and this is the thing to know before buying. The sitemap still lists jobs dated as far back as 2007. Walking it forwards, only 1 of the first 12 postings was from the past year. This actor therefore defaults to newestFirst: true, which starts from the most recently created listings — but datePosted is not a clean proxy for freshness either, because it records the original posting date and survives re-listing. If you need a live-market view, set postedWithinDays. Without it you are getting the archive along with the active board.
  • Some sitemap entries are dead. Taken-down jobs answer with a redirect and an empty body. Those are counted in the run summary as deadOrUnparseableListings and are never charged — you only pay for postings that actually returned content.
  • validThrough is not published. The column exists and is honest about being empty rather than being filled with a guess.
  • US only. PracticeMatch is a US physician recruiting board.
  • Coordinates are partial. Present on much of the physician board, mostly absent on the other two.
  • Format risk. Rows are built from each page's JSON-LD JobPosting, which parsed cleanly on 100% of sampled pages. If the site changes format the actor logs it and skips the row rather than silently emitting a blank one.

Output

Three ready-made views on the Output tab: Overview (the columns most people export), Compensation (pay only, for salary benchmarking by specialty and state) and Employers & geo (lead lists and territory mapping). A RUN_SUMMARY record in the key-value store reports rows pushed, rows billed, rows filtered out, dead listings and fetch failures.