This scholarship finder searches the web for scholarship pages for a field of study, a level and a year. It lists source-stated amounts and dates, sorted by the candidate deadline, and every row has a source URL. It is a Python CLI with no extra packages. This page shows a stored sample; there is no hosted demo.
The problem
Scholarship information is spread over university pages, foundations and large list sites. Deadlines are written in many formats, some pages are out of date and list pages mix many awards. Collecting a shortlist by hand means opening dozens of pages and copying dates. You need one table sorted by deadline, with the source of every row and a note on how sure each date is.
What the app does
- Searches the web for a field, level and year with two Desearch search routes.
- Finds explicit dates and nearby dollar amounts in each result.
- Marks dates near words such as deadline, due or apply by as likely deadlines, and flags the others.
- Opens up to 3 candidate pages to confirm the date on the page itself.
- Writes a sorted table to stdout, Markdown and CSV, plus a raw request log.
Deadlines and amounts are as stated by the source page. A matching date does not establish eligibility or official status. Check the official page before applying.
How it works
- Search.
POST /searchsends the query{field} {level} scholarships {year} application deadlinewith highlights.GET /websends a shorter deadline query. Use--no-webto skip the second search. - Find dates. The parser accepts English month names, ISO dates and US numeric dates with a four-digit year. Past dates and dates more than two calendar years ahead are dropped. No year is guessed.
- Read context. A deadline keyword within 80 characters before a date marks a likely deadline. A dollar amount in the same nearby sentence becomes the amount. Otherwise the amount is "not stated".
- Verify. Up to 3 candidate pages are read with
GET /web/extractas plain text. A page that needs JavaScript is retried once withjs=true. Each row becomes "confirmed on page", "date not found on page", "extract failed" or stays "snippet only". - Sort and export. Duplicates merge by normalized URL, date and name. Rows are sorted by deadline, and list sites are detected and flagged.
The code
This verbatim excerpt from scholarship_finder.py finds explicit dates in text. It relies on DATE_RE, MONTHS, re and dt defined in the full file.
def dates(text):
"""Return (date, start, end) for explicit, valid four-digit-year dates."""
found = []
for m in DATE_RE.finditer(text):
parts = re.findall(r'[A-Za-z]+|\d+', m.group())
try:
if m.lastgroup == 'md': month, day, year = MONTHS[parts[0].lower()], int(parts[1]), int(parts[2])
elif m.lastgroup == 'dm': day, month, year = int(parts[0]), MONTHS[parts[1].lower()], int(parts[2])
elif m.lastgroup == 'iso': year, month, day = map(int, parts)
else: month, day, year = map(int, parts)
found.append((dt.date(year, month, day), m.start(), m.end()))
except (ValueError, KeyError):
pass
return foundEndpoints
POST /searchGET /webGET /web/extract
Example output
From sample-output.md in the source folder, a run on 2026-10-30 for nursing, undergraduate, 2027. These are the first three of ten rows:
| Name | Amount | Deadline | Confidence | Source URL | Endpoint | Flags |
| --- | --- | --- | --- | --- | --- | --- |
| Healthcare Scholarships: Invitation to Apply by Nov 13 \| Health Professions Advising | not stated | 2026-11-13 | confirmed on page | [source](<https://hpa.princeton.edu/news/healthcare-scholarships>) | search | |
| 2027 Undergraduate Scholarship Application \| FNSNA.ORG | not stated | 2027-01-11 | extract failed | [source](<https://www.fnsna.org/2027-undergraduate-scholarship-application>) | search | no publish date |
| Top 50 Nursing Scholarships in 2026 | $8,000 | 2027-02-02 | date not found on page | [source](<https://scholaroo.com/nursing-scholarships/>) | web | no publish date |The confidence column shows how far each date was checked. Dates and amounts were copied from the sources on that date and may have changed since.
Run it yourself
Get the Python examples and open the scholarship finder folder. Use Python 3.10 or newer; no packages are needed. Create an API key in the console. Save it alone in ~/.desearch_api_key, or set DESEARCH_API_KEY.
git clone https://github.com/Desearch-ai/desearch-py-examples
cd desearch-py-examples/scholarship-finderThese commands are copied from the source README. The dry run prints the planned calls without a key or network.
python3 scholarship_finder.py --field nursing --level undergraduate --year 2027
python3 scholarship_finder.py --field nursing --level undergraduate --year 2027 --dry-run
python3 scholarship_finder.py --field nursing --level undergraduate --year 2027 --verify 0 --no-web --out ./resultsUse --hide-unclear to drop rows without a clear deadline, --limit to show more rows and --from-raw to rebuild results from a saved run with no new calls.
What it costs
The 2026-10-30 sample run made 6 calls for $0.00700 in total: $0.005 for /search with 10 results, $0.001 for /web and $0.0005 for each of two plain text extractions. One extraction that needed JavaScript and one JavaScript retry that failed were not charged. A successful JavaScript extraction probe cost $0.0015 and took 17.6 seconds on the same day.
These are dated measurements, not current price quotes. Use --no-js to skip the JavaScript retry, and check pricing before a larger run.
Ideas to extend it
- Run the finder for several fields and merge the CSV files into one shortlist.
- Rerun it each month and keep only rows whose deadline has not passed.
- Add a column for eligibility notes copied from each confirmed page.
- Send a reminder a week before each confirmed deadline.
