Skip to content
View dmanhlr's full-sized avatar
  • VietNam
  • 23:21 (UTC +07:00)

Block or report dmanhlr

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Content in all repositories owned by your account will be closed.
Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
dmanhlr/README.md

I turn messy websites, PDFs and spreadsheets into clean, verified data, and add AI where it measurably helps.

Case studies

Client needs: one clean spreadsheet from a trade-fair exhibitor directory — one row per email address, at most one contact per company, country as an ISO 3166-1 alpha-2 code, no duplicate companies, and a confidence score, because the work is paid per valid contact.

Delivered: Measured in this build, on a 300-company sample of the live directory: 248 sites crawled, 507 rows exported (359 with an email, 355 distinct addresses), 353 of 355 on a domain with an MX record, confidence bands 0 High / 88 Medium / 271 Low. On the Frankfurter Buchmesse 2026 predecessor prototype: 3,319 exhibitor entries from the API, 2,667 unique companies after dedupe, 256 companies with at least one email (9.6% of all; 42% of sites with a website), 252 / 256 emails on a domain with an MX record, 0 high-confidence rows without a paid data provider.

Client needs: a folder of PDF invoices, receipts and purchase orders in mixed layouts turned into one Excel workbook and one JSON file per document, on a schedule, without re-keying — and a clear list of which cells to double-check before trusting the numbers.

Delivered: Measured in this build against a labelled ground-truth set, indicative of these documents and not a benchmark: 7 real documents across 4 layouts, 37 fields checked — rules-only accuracy 62.2% (23/37), hybrid rules-plus-LLM 86.5% (32/37), hybrid review rate 52.4%, cost $0.0000/doc on gemini-3.5-flash-lite. On 6 deliberately hard synthetic layouts, 34 fields — rules-only and hybrid both 61.8% (21/34), review rate 30.6%; the LLM fallback added nothing on that set and the flat result is published.

Client needs: thousands of rows of free text — support tickets, reviews, complaints, inbound leads — tagged with a category and a one-line summary, the unsure rows flagged for a human, and a stated accuracy against real labels plus a cost per thousand rows.

Delivered: Measured in this build, one run on 2026-09-06 over a seeded CFPB Consumer Complaint sample with gemini-3.5-flash-lite: accuracy 0.804, macro-F1 0.647, 2,540 of the committed 4,000 rows scored, 1,460 rows left pending when the free tier throttled, 0 errors, measured cost $0.0000, projected cost ~$0.077 / 1,000 rows at OpenAI gpt-4o-mini list prices. The confidence flag is published as a weak filter: at 0.90 it catches 26% of all errors while flagging 11% of rows.

Client needs: a one-time export of every active listing for a list of suburbs from a bot-protected property portal into one CSV the client imports by hand — no automation, no scheduled re-runs, no integration.

Delivered: Fixture-verified in this build (synthetic pages, no live run): 2 search pages, 28 listing rows seen, 26 valid with 26 unique listing_url and 0 agency cards, 2 dropped with a reason, 54-test suite (50 pass + 4 skip without Node). Predecessor prototype, live manual browsing on 2026-08-30: 53 rows on the first pass, then 26 rows / 26 unique URLs / 0 agency cards / 0 dead links after fixes. Live re-verification on 2026-09-08: 37 rows, 33 unique URLs, 0 agency cards, 4 dead links. The Playwright route was not run end to end.

Client needs: a niche brief turned into a ranked, contactable list of 200+ podcasts from public sources — name, website, size, YouTube, email, phone, format and location — US and Canada first, then the EU block, then Australia and New Zealand, with a stated completeness for every column.

Delivered: Measured in this build, one run on 2026-09-07 (--limit 200, free gemini-3.1-flash-lite): 8,163 raw rows narrowed to 2,384 unique feeds, 200 exported; coverage of the 200 rows — website 200 / 200 (100%), email 160 / 200 (80%), phone 14 / 200 (7%), YouTube subscribers 66 / 200 (33%), format 6 / 200 (3%), location 23 / 200 (11.5%); 360 LLM requests, $0.0000 on the free tier. Predecessor prototype: 800 rows exported, coverage website 100%, email 74% (593), phone 6% (48), YouTube 4% (31), format 0%, location 0.25%.

What these five have in common

  • Every deliverable ships with a confidence or review column, so the client knows exactly which rows to check before trusting the batch.
  • Every claim in every README is a measured number carried with its denominator — 32/37 fields, 355 of 355 addresses, 160 / 200 rows — not a rounded headline.
  • Each repo runs offline from a fresh clone with one demo command: no API key, no network, synthetic fixtures, deterministic output.
  • Where a feature did not help, the number that shows it is published rather than hidden. In pdf-data-extractor the LLM fallback was called on every synthetic document that rules could not read and hybrid accuracy still stayed at 61.8% (21/34), identical to rules-only — that flat result is in the README.

How I work

  • A free sample on your own data before you commit to the job.
  • Delivery in milestones, each one a working piece you can check.
  • Async on Upwork, with a written daily update.
  • Nothing is guessed: a value the source does not support is left empty and flagged for review, never filled with a plausible-looking number.

Stack

Python, Playwright, pandas, pdfplumber, openpyxl, BeautifulSoup, OpenAI-compatible LLM APIs, Chrome extensions (Manifest V3), GitHub Actions.

Links

Pinned Loading

  1. exhibitor-leadgen-pipeline exhibitor-leadgen-pipeline Public

    Event exhibitor directory -> cleaned company list -> contact extraction (regex + LLM) -> email verification -> scored Excel, with an honest funnel and a confidence score on every row.

    Python

  2. pdf-data-extractor pdf-data-extractor Public

    Hybrid rules+LLM extraction of structured data from PDF invoices, receipts and purchase orders into Excel and JSON, with per-field confidence and a Review sheet.

    Python

  3. llm-bulk-classifier llm-bulk-classifier Public

    Classify thousands of rows of free text with an LLM: batching, cache, resume, USD budget guard, low-confidence review flags, and accuracy measured against real labels. Reports its own cost and accu…

    Python

  4. property-listing-extractor property-listing-extractor Public

    Export clean listing rows from a bot-protected property portal: a Chrome extension for browsing plus a proxy-gated Playwright route, one shared parser tested to agree.

    Python

  5. podcast-discovery-pipeline podcast-discovery-pipeline Public

    Niche keywords to a ranked, contactable podcast list from several public sources, with per-column coverage and per-run cost reported.

    Python