Skip to main content

Goodreads Icon

Goodreads User Scraper

Export Goodreads profile, shelves, books, and authors to JSON

Version  Downloads 

CLI Demo

Contents

Usage

Use pipx or uv — both install the CLI from PyPI.

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.

pipx install goodreads-user-scraper      # or: uv tool install goodreads-user-scraper
goodreads-user-scraper --user_id <your id>

Run once without installing

Best for one-off use. Downloads and runs the CLI in a temporary environment: no install step, no $PATH changes.

pipx run goodreads-user-scraper --user_id <your id>
# or: uvx goodreads-user-scraper --user_id <your id>

Output

Data is written to --output_dir (default goodreads-data/):

goodreads-data/
├── user.json                          # profile: name, average rating, rating/review counts
└── books/
    ├── 4395.The_Grapes_of_Wrath.json  # one JSON file per book
    └── …

Each books/*.json looks like this — your rating, dates_read, shelves, and exclusive_shelf (the one status shelf, e.g. read, or null) come from your library; the author is nested:

{
  "book_id_title": "4395.The_Grapes_of_Wrath",
  "book_id": "4395",
  "book_title": "The Grapes of Wrath",
  "book_description": "The Grapes of Wrath is a landmark of American literature. A portrait of the conflict between the powerful and the powerless…",
  "book_url": "https://www.goodreads.com/en/book/show/4395.The_Grapes_of_Wrath",
  "book_image": "https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1511302892i/4395.jpg",
  "book_series_uri": null,
  "year_first_published": "1939",
  "num_pages": 455,
  "genres": ["Classics", "Fiction", "Historical Fiction", "Literature", "Novels", "School", "Historical"],
  "num_ratings": 1011464,
  "num_reviews": 31088,
  "average_rating": 4.03,
  "author": {
    "author_id_title": "585.John_Steinbeck",
    "author_id": "585",
    "author_name": "John Steinbeck",
    "author_url": "https://www.goodreads.com/author/show/585.John_Steinbeck",
    "author_image": "https://images.gr-assets.com/authors/1182118389p5/585.jpg",
    "author_description": "John Ernst Steinbeck was an American writer. He won the 1962 Nobel Prize in Literature…"
  },
  "rating": 5,
  "dates_read": ["May 03, 2020"],
  "shelves": ["read", "2020", "2020s-favorites"],
  "exclusive_shelf": "read"
}

The two description fields are truncated here; the rest is real output. Without a cookie only user.json is written (see Authentication); --skip_authors omits the nested author.

What the CLI looks like in other states
Scenario Demo
Nothing to do Nothing-to-do demo
No cookie No-cookie demo
Invalid cookie Invalid-cookie demo

Arguments

Flag Description Default
--user_id Required. The user whose data to scrape (find your user id).
--output_dir Directory where scraped data is written. goodreads-data
--cookie Your Goodreads session cookie (the full Cookie: request-header value); required for shelf scraping — see Authentication. None
--cookie_file Path to a text file containing your session cookie. None
--skip_user_info Skip scraping user information.
--skip_shelves Skip scraping shelves. Books (and their authors) are scraped from your shelves, so this skips them too.
--skip_authors Skip scraping authors.

Authentication

Shelf scraping requires a cookie — Goodreads hides shelf data behind login. Without one you get the profile only; with one you also get shelves, books, and authors.

Getting your session cookie

  1. Sign in to Goodreads in your browser.
  2. Open DevTools (Cmd/Ctrl+Shift+I) and switch to the Network tab.
  3. Refresh the page, then click any goodreads.com request in the list.
  4. In the request Headers, find the Cookie: header and copy its full value.

Passing the cookie

In order of precedence (first one set wins):

  1. --cookie "<cookie string>"
  2. GOODREADS_COOKIE environment variable
  3. --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.

FAQ

Missing profile or shelf data?
  • Your own account: pass your session cookie (see Authentication) — your profile, shelves, and books all scrape, even on a private profile.
  • Another user's account: what you can scrape depends on their profile privacy setting. Shelves always require your cookie (see Authentication).
    • Anyone: the profile scrapes even without a cookie.
    • Goodreads members only: pass your cookie — any signed-in account works.
    • Friends only: pass your cookie, and your account must be their friend.
Hit a rate-limit or timeout?

Transient errors (timeouts, 429, 5xx) are retried with exponential backoff. If a book still can't be fetched, the run finishes the rest, logs the skips, and exits with a non-zero status so you know the export is incomplete — re-run to fetch the missing books (already-saved books are skipped). A profile or shelf-listing failure stops the run early, since nothing else can proceed.

Can I export to a SQLite database (or another format)?

The scraper outputs JSON, which converts cleanly to other formats. For SQLite, sqlite-utils infers the schema and handles indexes and upserts. Combine the per-book files and load them into a table keyed on book_id:

goodreads-user-scraper --user_id <id> --cookie "<cookie>"
jq -s . goodreads-data/books/*.json | sqlite-utils upsert books.db books - --pk book_id
sqlite-utils create-index --if-not-exists books.db books book_title

Re-running the scraper fetches only new books and upsert updates the table in place, so the pipeline is safe to rerun on a schedule. The nested author and shelves come through as JSON columns — query them with SQLite's JSON functions (json_extract, json_each). See #38 for context.

Contributing

Contributions are welcome! See CONTRIBUTING.md for local development setup. To report a bug or request a feature, open an issue; for usage questions, start a thread in Discussions.

Licensed under MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

goodreads_user_scraper-2.5.1.tar.gz (21.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

goodreads_user_scraper-2.5.1-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

Details for the file goodreads_user_scraper-2.5.1.tar.gz.

File metadata

  • Download URL: goodreads_user_scraper-2.5.1.tar.gz
  • Upload date:
  • Size: 21.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for goodreads_user_scraper-2.5.1.tar.gz
Algorithm Hash digest
SHA256 adfd59cb3867f7c5c48f830c41f36ec925b363e887ca808f181cf4efba246e4a
MD5 9c24739ac42b4d79c9fd3c82c16bbd99
BLAKE2b-256 3157f5a62788577536a521ba0d914fd89a262e3cf232d597dbf8c68abde8cccd

See more details on using hashes here.

Provenance

The following attestation bundles were made for goodreads_user_scraper-2.5.1.tar.gz:

Publisher: publish.yml on YashTotale/goodreads-user-scraper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file goodreads_user_scraper-2.5.1-py3-none-any.whl.

File metadata

File hashes

Hashes for goodreads_user_scraper-2.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 251d3a1e96714b32799dd145c007effd3981c3115403a8c00257917752665a66
MD5 087e48cc6aae42091a3c8545de4bdb41
BLAKE2b-256 24aafb514c758fb10ab0c69904614002fcec52c80dade9516f7a7a84c5686609

See more details on using hashes here.

Provenance

The following attestation bundles were made for goodreads_user_scraper-2.5.1-py3-none-any.whl:

Publisher: publish.yml on YashTotale/goodreads-user-scraper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

2.5.1 This release

2 files

2.5.0

2 files

2.4.4

2 files

2.4.3

2 files

2.4.2

2 files

2.4.1

2 files

2.4.0

2 files

2.3.0

2 files

2.2.0

2 files

2.1.0

2 files

2.0.0

2 files

1.2.5

2 files

1.2.4

2 files

1.2.3

2 files

1.2.2

2 files

1.2.1

2 files

1.2.0

2 files

1.1.0

2 files

1.0.0

2 files

0.0.10

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page