Scripts
Scripts
Google Scholar citations
Refresh _data/citations.json (profile stats, per-paper counts, citing works, leaderboard):
python3 scripts/update_scholar_citations.py
python3 scripts/update_scholar_citations.py --delay 2.5
The fetcher is ordinary HTTP (stdlib only). Headless Chromium gets a Scholar CAPTCHA from the same address that still serves the pages to a normal request.
Options:
--delay 2.5— pause between requests--no-merge— do not union with existing citing-paper lists--dry-run— print JSON to stdout
Scheduled refresh (polsci server)
The weekly refresh runs on the polsci server, not on GitHub Actions. GitHub runners are often rate-limited; the university server is not, as long as the request is plain HTTP rather than headless Chrome.
Setup on polsci (~/scholar-updater/):
venv/— Python venv with Playwright + Chromium headless shellsite/— clone of this repo, pushed via a repo-scoped deploy key (~/.ssh/id_ed25519_ghdeploy, write access to this repository only)update-citations.sh— fetch/reset to origin/master, scrape, commit + push only if_data/citations.jsonchanged- cron: Mondays 06:15 (server time), logs to
~/scholar-updater/cron.log
The GitHub Action (.github/workflows/update-scholar-citations.yml) remains as a manual fallback (workflow_dispatch only) and will usually fail with a CAPTCHA. Merge-on-truncate keeps previous citing-paper lists if a scrape is partial.
