Scrape Goodreads User Data: Profile, Book Shelves, Books, Authors
Project description
Scrape Goodreads User Data: Profile, Book Shelves, Books, Authors
Contents
Usage
Install once, then run
Best for repeat use. Installs the CLI into an isolated environment and adds the goodreads-user-scraper command to your shell.
Using pipx:
pipx install goodreads-user-scraper
goodreads-user-scraper --user_id <your id> --output_dir goodreads-data
Or with uv:
uv tool install goodreads-user-scraper
goodreads-user-scraper --user_id <your id> --output_dir goodreads-data
Run once without installing
Best for one-off use. Downloads and runs the CLI in a temporary environment: no install step, no $PATH changes.
Using pipx:
pipx run goodreads-user-scraper --user_id <your id> --output_dir goodreads-data
Or with uvx (ships with uv):
uvx goodreads-user-scraper --user_id <your id> --output_dir goodreads-data
Arguments
--user_id
- Description: The user whose data should be scraped. Find your user id using these directions.
- Required: Yes
--output_dir
- Description: The directory where all scraped data will be output.
- Required: No
- Default:
goodreads-data
--skip_user_info
- Description: If passed, skip scraping user information.
- Required: No
--skip_shelves
- Description: If passed, skip scraping shelves.
- Required: No
--skip_authors
- Description: If passed, skip scraping authors.
- Required: No
--cookie
- Description: Your Goodreads session cookie (the full
Cookie:request-header value). Required for shelf scraping — see Authentication. - Required: No
- Default: None
--cookie_file
- Description: Path to a text file containing your Goodreads session cookie. Used only if
--cookieis not passed andGOODREADS_COOKIEis not set. - Required: No
- Default: None
Authentication
Shelf scraping requires authentication — Goodreads hides shelf data behind login, and the tool gathers books and authors from your shelves. So without a cookie you get a profile only; a cookie adds shelves, books, and authors, and works on your own private profile too.
Getting your session cookie
- Sign in to Goodreads in your browser.
- Open DevTools (Cmd/Ctrl+Shift+I) and switch to the Network tab.
- Refresh the page, then click any
goodreads.comrequest in the list. - In the request Headers, find the
Cookie:header and copy its full value.
Passing the cookie
In order of precedence (first one set wins):
--cookie "<cookie string>"GOODREADS_COOKIEenvironment variable--cookie_file <path-to-file>
Cookies typically last several weeks. If you see a "Cookie appears invalid or expired" error, re-grab the cookie from your browser.
If no cookie is provided, shelf scraping is skipped with a warning. Pass --skip_shelves to suppress the warning.
Troubleshooting
Missing profile or shelf data?
- Your own account: pass your session cookie (see Authentication). Every request is authenticated, so your profile, shelves, and books all scrape even when your profile is private — there's no need to change any Goodreads privacy settings.
- Another user's account: you can only see what your logged-in account is allowed to, so their profile must be publicly viewable. Shelves still require your cookie.
Development
-
Clone the GitHub repository
git clone https://github.com/YashTotale/goodreads-user-scraper.git
-
Run the install script
bash scripts/install.sh -
Make changes
-
Run the unit tests
pytest
These run against saved Goodreads HTML in
tests/fixtures/— no network, no cookie. This is the CI gate on every push and PR.When Goodreads changes its markup, refresh the fixtures with
scripts/capture_fixtures.py(reads your cookie from.goodreads-cookieif present), then re-runpytest. -
Optionally run the live smoke test
bash scripts/test.shThis scrapes the real Goodreads site end to end. To include shelf scraping, save your Goodreads cookie to a gitignored
.goodreads-cookiefile in the repo root — the test script picks it up automatically. CI runs this monthly (seeintegration.yml) to catch Goodreads markup changes.
Publishing
Publishing is automated via GitHub Actions using PyPI Trusted Publishing (OIDC) — no API tokens are stored.
Run the publish script with the version bump type:
bash scripts/publish.sh <patch|minor|major>
The script bumps the version, creates a git tag, and pushes it. The publish workflow builds the distribution and uploads it to PyPI on any pushed v* tag.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file goodreads_user_scraper-2.1.0.tar.gz.
File metadata
- Download URL: goodreads_user_scraper-2.1.0.tar.gz
- Upload date:
- Size: 14.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61de675bec8070a2fa3e33bd3ae1d94cda74804436e79470b39e32169fbedc7c
|
|
| MD5 |
d3103a526e1f16542d218c70a6cc1768
|
|
| BLAKE2b-256 |
0e965883dd0bd37bdd3866c0459e858ccb6def029445adf26295f560c726be7e
|
Provenance
The following attestation bundles were made for goodreads_user_scraper-2.1.0.tar.gz:
Publisher:
publish.yml on YashTotale/goodreads-user-scraper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
goodreads_user_scraper-2.1.0.tar.gz -
Subject digest:
61de675bec8070a2fa3e33bd3ae1d94cda74804436e79470b39e32169fbedc7c - Sigstore transparency entry: 1667009640
- Sigstore integration time:
-
Permalink:
YashTotale/goodreads-user-scraper@f9e8559d692a288f3aab1ee3a0c2fe8cf2206783 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/YashTotale
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f9e8559d692a288f3aab1ee3a0c2fe8cf2206783 -
Trigger Event:
push
-
Statement type:
File details
Details for the file goodreads_user_scraper-2.1.0-py3-none-any.whl.
File metadata
- Download URL: goodreads_user_scraper-2.1.0-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ace296b6a557b67ff57145f78209a6b81d3745df19bd9d6747ee3c05ce5ea2c2
|
|
| MD5 |
76e09d1012c84f245e529cf930501c31
|
|
| BLAKE2b-256 |
e990badd97952b630013c37f06414c0d8810ac12afa0221bff5223e36e2d79b2
|
Provenance
The following attestation bundles were made for goodreads_user_scraper-2.1.0-py3-none-any.whl:
Publisher:
publish.yml on YashTotale/goodreads-user-scraper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
goodreads_user_scraper-2.1.0-py3-none-any.whl -
Subject digest:
ace296b6a557b67ff57145f78209a6b81d3745df19bd9d6747ee3c05ce5ea2c2 - Sigstore transparency entry: 1667009751
- Sigstore integration time:
-
Permalink:
YashTotale/goodreads-user-scraper@f9e8559d692a288f3aab1ee3a0c2fe8cf2206783 -
Branch / Tag:
refs/tags/v2.1.0 - Owner: https://github.com/YashTotale
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f9e8559d692a288f3aab1ee3a0c2fe8cf2206783 -
Trigger Event:
push
-
Statement type: