How to scrape Google Scholar with Python

One endpoint, every paper as clean JSON, saved to CSV.

Free to try, no card Title, authors, year, citations Clean JSON, no HTML parsing
PULLED LIVE FROM THE API, AUGUST 2, 2026

How do you scrape Google Scholar?

Scraping Scholar yourself means driving a browser, beating the block page, and parsing markup that shifts. Here you send one HTTP request and read JSON. Three steps:

  1. 1

    Create a free account. Try it free, no card needed.

  2. 2

    Copy your API key. It is on the dashboard right after signup.

  3. 3

    Run the code below. Start with the curl test, then the Python script.

First a quick test with curl:

# one charge per search, however many results come back; empty searches cost nothing curl "https://crustapi.com/v1/search?type=scholar&q=climate change" -H "x-api-key: YOUR_KEY"

Then the same call in Python with the requests library. Install it with pip install requests, drop in a key, and run. The results live in the organic array:

# pip install requests, then run this file import requests resp = requests.get( "https://crustapi.com/v1/search", params={"type": "scholar", "q": "climate change"}, headers={"x-api-key": "YOUR_KEY"}, ) data = resp.json() for paper in data["organic"]: print(paper["title"], paper["year"], paper["citedBy"])

Here are two of the results that came back, shown as CSV so they drop straight into Sheets or a reference manager:

titlepublicationInfoyearcitedBylink
Modern global climate changeTR Karl, KE Trenberth - science, 2003 - science.org20033061https://www.science.org/doi/abs/10.1126/science.1090228
Climate change and the ecologistW Thuiller - Nature, 2007 - nature.com20071114https://www.nature.com/articles/448550a

Scholar returns one page of results per call. To go deeper, add a page number and loop, collecting every result into one list:

# pull the first five pages into one list papers = [] for page in range(1, 6): r = requests.get( "https://crustapi.com/v1/search", params={"type": "scholar", "q": "climate change", "page": page}, headers={"x-api-key": "YOUR_KEY"}, ) papers += r.json()["organic"]

Change q to any Scholar query, like graph neural networks or crispr gene editing.

WHAT EVERY RESULT INCLUDES

What data do you get?

Every result comes complete, so a citation list needs no second call. When Scholar lists a free copy, pdfUrl holds a PDF and htmlUrl a web page; both are null when Scholar shows none. Here is one paper as CSV:

titlepublicationInfoyearcitedBylinkpdfUrlhtmlUrl
Modern global climate changeTR Karl, KE Trenberth - science, 2003 - science.org20033061https://www.science.org/doi/abs/10.1126/science.1090228https://www.agro.uba.ar/users/fernande/Karl%26Trenberth2003.pdf

Or the same record as JSON, exactly as the API returns it:

// one result in full { "title": "Modern global climate change", "link": "https://www.science.org/doi/abs/10.1126/science.1090228", "publicationInfo": "TR Karl, KE Trenberth - science, 2003 - science.org", "snippet": "... social problem, its regional and global environmental consequences are also of great ... global air-quality issues, and regional and global environmental impacts, including climate change...", "year": 2003, "citedBy": 3061, "pdfUrl": "https://www.agro.uba.ar/users/fernande/Karl%26Trenberth2003.pdf", "htmlUrl": null, "id": "Sq6DrEx1vacJ", "position": 3 }
HOW IT COMPARES

vs writing your own scraper

You can build a Scholar scraper with a headless browser and a parser, and plenty of tutorials show how. The trade is that Scholar blocks automated traffic quickly, and the layout keeps moving. Here is the difference in practice.

Writing it yourselfCrustAPI
SetupInstall a headless browser, get past the block page and CAPTCHAsOne GET request, no browser
OutputParse the HTML yourself; fields break when the layout changesClean JSON from the API, or the same rows as CSV
MaintenanceFix the scraper each time the page changesWe keep it working
Free tierFree, but you pay in time and blocked requests$6 of free usage each month
Cost modelServer, proxy, and developer timeOne charge per search, whatever the result count; empty searches free
Storing the dataYours to manageNo storage limits. Export to CSV or a database
PRICING

How much does scraping Google Scholar cost?

Each successful search is billed once at your Google Search rate, however many results come back. Empty searches cost nothing. Paid funds never expire.

DepositGoogle Search / 1,000 requestsMaps / 1,000 businessesLinkedIn reads / 1,000 requestsPeople, Jobs, Refresh / 1,000 units
$10+$1.00$1.96$6.00$1.96
$149+$0.76$1.49$4.50$1.49
$549+$0.56$1.10$3.30$1.10
$1,999+$0.41$0.80$2.45$0.80
$6,500+$0.33$0.65$1.95$0.65
$27,500+$0.28$0.55$1.65$0.55
$50,000+$0.26$0.50$1.50$0.50
$100,000+$0.20$0.40$1.50$0.40

Every eligible account gets $6 of free usage monthly. Each deposit keeps its prices until spent; paid funds never expire. People and Jobs bill per successful search, Refresh per accessible profile. Full profiles in People use the read rate per full profile. See all billing details.

Larger deposits unlock lower endpoint prices. Each deposit keeps its prices until spent. See the full deposit table on the pricing page. Prices in USD, ex-tax.

The endpoint's full field list and pricing detail live on the Google Scholar API page.

Run your first Scholar search free
Try it free. No card, no contract.
Try for free
THE LAST STEP

Save the results to a CSV file

Because the response is plain JSON, Python's built-in csv module writes it to a file in a few lines. No extra libraries. This reads every result from the search and writes one row each:

# save every result to a CSV file with the built-in csv module import csv, requests data = requests.get( "https://crustapi.com/v1/search", params={"type": "scholar", "q": "climate change"}, headers={"x-api-key": "YOUR_KEY"}, ).json() with open("papers.csv", "w", newline="") as f: writer = csv.writer(f) writer.writerow(["title", "publicationInfo", "year", "citedBy", "link", "pdfUrl"]) for p in data["organic"]: writer.writerow([p["title"], p["publicationInfo"], p.get("year", ""), p.get("citedBy", ""), p.get("link", ""), p.get("pdfUrl", "")])

Open papers.csv in Sheets or Excel and you have a finished reading list. Swap the query, run it again, and append to build a bigger literature dataset.

WHO IT'S FOR

Who scrapes Google Scholar?

Related: Google Scholar API · Google Search API · Google Patents API · Scrape Google Maps with Python · API docs

FAIR PLAY

When a different tool fits better: Google Scholar has no official API, so there is no formal SLA on this data. This endpoint returns the same public search results anyone sees on scholar.google.com, which is what most citation research and literature-review work needs. For licensed full text or bulk metadata, providers like Crossref and Semantic Scholar run their own APIs.

BEFORE YOU ASK

Common questions

No. With the CrustAPI endpoint you send one HTTP request with the requests library and get clean JSON back. There is no browser to drive and no HTML to parse, so the code above is the whole scraper.

Title, authors and venue, publication year, citation count, a link to the paper, and a direct full-text link when Scholar lists one: pdfUrl when the free copy is a PDF, htmlUrl when it is a web page. Enough to build a citation list or a research dataset without a second call.

Scholar is quick to stop automated traffic, which is why a raw script tends to get blocked fast. The endpoint handles that layer for you, so you just read JSON.

Add a page number to the request and loop, as shown above. Each call returns one page of results, and you pay one charge per search, however many results come back.

The response is plain JSON, so Python's built-in csv module writes it to a file in a few lines. The Save to CSV section above has the exact code, no extra libraries.

Yes. Try it free, no credit card, and paid funds never expire. That is enough to pull several full result pages while you build.

WORKS WITH YOUR STACK

Try it on a topic you know

the free plan covers a real search. Run one query and look at the JSON that comes back.

Try for free
No credit card required