Python Developer for Permit Portal Scrapers

Posted 5 days ago

Worldwide

Summary

Overview We collect building permit records from municipal and county permitting portals across the US. We need a Python developer to build one scraper per jurisdiction, on an ongoing basis. We have many jurisdictions to cover, so consistent quality means steady repeat work. Compensation: $30 USD per completed, accepted scraper. Fixed price, one jurisdiction per milestone. Payment is released when the scraper meets the acceptance criteria below. Every scraper follows the same spec, so after the first two or three the work becomes largely repeatable. Read this part carefully — it's where most submissions fail Pulling the permit page is the easy half. The two requirements below are the core of the job, and a scraper that skips them will not be accepted. 1. Missing owner name must be resolved from public property records. Many permit records list no owner. When Owner Name is blank, the script must look it up from the county property appraiser, tax collector, or equivalent public property-records source, using the Job Address as the key. This means parsing and normalizing the address, querying the county's public property search, and pulling the owner of record. Each county exposes this differently — some have a JSON endpoint, some a form-post search, some a GIS/parcel service. Finding and using the right one for your assigned jurisdiction is part of the job. 2. A contractor company name must produce an email and phone number. If the record gives you a contractor company, that alone is enough to trigger the lookup — do not skip enrichment just because there's no individual contractor name. The email and phone fields are the most valuable output of this entire scraper. Deliverable One single standalone .py file per jurisdiction. No multi-file frameworks, no shared imports between scrapers, no build steps. Each file must run independently on Windows via Task Scheduler. Automation 100% autonomous. No manual clicks, no prompts, no manual browser interaction. It runs on a schedule unattended. Data extraction 20 data points per permit record. The full field list and the classification rules for the derived fields are provided on hire. They cover permit identifiers and dates, permit and property classification, project description, address, project value, status, and the owner / applicant / contractor contact set. If a field isn't available after the lookup steps above have been attempted, leave it blank and continue to the next record. The script must never stop or throw on missing data. Contractor contact enrichment Work these steps in order and stop at the first that returns a result. Never halt on a failed step — log it and move on. Applicant contact info on the permit record — if the applicant's email or phone is listed, copy it into the contractor contact fields. State contractor licensing database — query the state's public license lookup by contractor name and/or company (e.g. FL DBPR, CA CSLB). Parse for email and phone. The contractor's own website — locate the business site and pull contact details from the contact/about page, including structured data (JSON-LD, microdata, mailto:/tel: links) where present. Public business listings — where a listing is publicly accessible and its terms permit automated retrieval, pull the published business phone/email. If nothing is found after all steps, leave the fields blank and continue. Contact cache The script must save every email and phone number it finds to a local file so the same contractor is never looked up twice. Before running any external lookup, check the cache first — if we already have that contractor's email and phone from a previous run, reuse it and skip the lookup entirely. Google Sheets output Records are appended to a designated Google Sheet via the Sheets API using service account credentials we provide. The push happens inside the same script — no manual export or copy-paste. Reliability requirements Randomized delays between requests (1–4s). No rapid-fire request bursts. Respect Retry-After headers. Persistent session so cookies carry across page loads within a domain (requests.Session or a Playwright context). Exponential backoff on 429/503 (5s → 10s → 20s, max 3 retries). On a hard block, log the URL and skip rather than crash. Where the portal genuinely requires JS to render, use Playwright or Selenium headless. Console-only diagnostics. Do not write screenshots or HTML dumps to disk. sys.stdout.reconfigure(encoding='utf-8') for clean Unicode output under Windows Task Scheduler. Acceptance criteria A scraper is accepted when it: runs end-to-end unattended on a fresh machine pulls the full available record set for the jurisdiction, not just page one populates all 20 data points where the data exists resolves owner name from public property records on records where the permit itself left it blank returns email and phone for records that carry a contractor company name writes to the target Sheet completes without an unhandled exception

  • $30.00

    Fixed-price
  • Intermediate
    Experience Level
  • Remote Job
  • Complex project
    Project Type
Skills and Expertise
Mandatory skills
Python
Scrapy
Nice-to-have skills
Django
Machine Learning
Activity on this job
  • Proposals:20 to 50
  • Last viewed by client:4 days ago
  • Interviewing:
    0
  • Invites sent:
    0
  • Unanswered invites:
    0
About the client
Member since Jul 17, 2025
  • USA
    Green Cove Springs3:40 AM
  • $30K total spent
    11 hires, 2 active
  • 117 hours
  • Manufacturing & Construction
    Mid-sized company (10-99 people)

Explore similar jobs on Upwork

Freelancers for Student Data CollectionFixed-price‐ Posted 3 weeks ago
Data Entry
Data Mining
Microsoft Excel
English
Data Entry
Data Scraping
Microsoft Excel

How it works

  • Post a job icon
    Create your free profile
    Highlight your skills and experience, show your portfolio, and set your ideal pay rate.
  • Talent comes to you icon
    Work the way you want
    Apply for jobs, create easy-to-by projects, or access exclusive opportunities that come to you.
  • Payment simplified icon
    Get paid securely
    From contract to payment, we help you work safely and get paid securely.
Want to get started? Create a profile

About Upwork

  • Rating is 4.9 out of 5.
    4.9/5
    (Average rating of clients by professionals)
  • G2 2021
    #1 freelance platform
  • 49,000+
    Signed contract every week
  • $2.3B
    Freelancers earned on Upwork in 2020

Find the best freelance jobs

Growing your career is as easy as creating a free profile and finding work like this that fits your skills.

Trusted by

  • Microsoft Logo
  • Airbnb Logo
  • Bissell Logo
  • GoDaddy Logo